C ++: Primer clase de error literales llama a la función (el ejemplo dado libro P268)


1. Antecedentes

  Encontrado al leer a C ++ cartilla en la página 268 después de los buenos ejemplos de error de programación.

#include <iostream>
using namespace std;
class Debug
{
public:
    constexpr Debug(bool b = true) : hw(b), io(b), other(b){};
    constexpr Debug(bool h, bool i, bool o) : hw(h), io(i), other(o){};
    constexpr bool any()
    {
        return hw | io | other;
    }
    void set_io(bool b)
    {
        io = b;
    }
    void set_hw(bool b)
    {
        hw = b;
    }
    void set_other(bool b)
    {
        other = b;
    }

private:
    bool hw;
    bool io;
    bool other;
};

int main()
{
    constexpr Debug io_sub(false, true, false);
    if(io_sub.any())
    {
        cerr << "print approptiate error messages" << endl;
    }
    constexpr Debug prod(false);
    if(prod.any())
    {
        cerr << "print an error message" << endl;
    }
    return 0;
}

error del sistema

2. Conocimientos básicos (que se puede omitir)

  1. expresión constante . El valor no cambiará y será capaz de obtener resultados en el proceso de compilación de expresión.
const int max_files = 20; // max_files是常量表达式
const int limit = max_files + 1; // limit是常量表达式
int staff_size=27; // staff_size不是常量表达式,因为staff_size不是常量
const int sz = get_size(); // sz不是常量表达式,因为get_size()结果未知
  1. las variables constexpr . Las variables declaradas constexpr debe haber una constante , y debe ser inicializado con expresiones constantes.
constexpr int mf = 20;
constexpr int limit = mf + 1;
const int *p1 = nullptr; //p1是指向常量的指针
int * const p2; //p2本身是常量
constexpr int *p3 = nullptr; // p3本身也是常量
  1. Tipo literal . tipos aritméticos, referencias y punteros pertenecientes tipos literales, clases personalizadas, la biblioteca IO, tipo de cadena no es de lo literal tipo. Único tipo literal a constexpr declare.

  2. constexpr función . La función puede utilizarse para expresiones constantes. El tipo de retorno y una función de todos los tipos de parámetros son los tipos de literales, funciones, y sólo el cuerpo debe tener una instrucción de retorno. constexpr función no devuelve necesariamente una expresión constante.

constexpr int new_sz() {return 42;}
constexpr int foo= new_sz();
  1. polimerización Clase . Cuando las condiciones siguientes son una clase, la clase es la polimerización Clase: Todos los miembros son públicos; no define ningún constructor; no dentro de la clase inicializador; no hay clases base y funciones virtuales.

  2. clase literales . Miembros de datos son tipos literales de polimérico clase constante literal es de clase, excepto la siguiente es la clase de las condiciones de todos los literales: el tipo de miembros de datos son literales; clase constexpr debe contener al menos un constructor, si una que contiene los miembros de datos de clase del valor inicial, el valor inicial de los miembros de tipo construido debe ser una expresión constante, o si algunos de los miembros que pertenecen a un tipo de clase, el valor inicial de los propios miembros debe ser utilizado constexpr constructor; debe utilizar el destructor clase predeterminada definición, el miembro responsable de la destrucción de la clase de objeto.

3. Analizar

  1. Visto por el ejemplo, io_sub y prod es variable de constexpr . Por lo tanto io_sub y prod en sí es una constante , que corresponde al tipo de const la depuración .
//constexpr Debug等价于 const Debug 
constexpr Debug io_sub(false, true, false);
constexpr Debug prod(false);
  1. función miembro cualquier función () es una constexpr. En c ++ 11 estándar, la función constexpr es métodos constantes, en 14 c ++ estándar, la función constexpr no es un funciones miembro constante. Mi función constexpr predeterminado compilador no es una constante funciones miembro.
constexpr bool any()
//c++11标准下等价于
bool any () const
//c++14标准下等价于
bool any()
  1. Cuando el objeto constante io_sub llamando a la función miembro de cualquier (), esta = & io_sub. Este tipo es de depuración * const, seleccione depuración y, io_sub es const Dedug. tipo de puntero en general, debe coincidir con el tipo de objeto al que apunta, por lo error de llamada. Lo mismo es cierto prod.
io_sub.any()
prod.any()

4. corrección

  Dado que el valor por defecto C ++ estándar bajo, la función constexpr no es una constante funciones miembro, y io_sub y prod objetos son constantes, sólo puede llamar a métodos constantes. Puede ser cualquier funciones miembro const () para modificar las dos formas siguientes:

  1. En cualquier const () más después de hacer funciones miembro const.
constexpr bool any() const
{
	return hw | io | other;
}

Los resultados operativos

  1. Utilice C ++ 11 estándar de tiempo de compilación, es la función por defecto es constexpr métodos constantes.

Los resultados operativos

5. Resumen

  1. Las variables declaradas constexpr debe ser una constante.
  2. Declarado de la clase como una función de constexpr no es necesariamente función miembro constante, que se determina por el compilador de C ++ estándar. Durante la programación, de acuerdo con sus necesidades de la mejor iniciativa para añadir const.
  3. Un constructor no puede ser una constante funciones miembro, pero constructor de la clase literales puede ser función constexpr.
Publicado 77 artículos originales · ganado elogios 25 · Vistas a 10000 +

Supongo que te gusta

Origin blog.csdn.net/qq_34801642/article/details/104634709
Recomendado
Clasificación