El uso de C ++ 11 auto y decltype

auto

En la programación C ++, a menudo es necesario asignar el valor de una expresión a una variable, y es necesario saber claramente de qué tipo es la variable al declarar la variable. Sin embargo, esto no es tan fácil de hacer y, a veces, no es posible en absoluto. Para resolver este problema, el nuevo estándar C ++ 11 introdujo el especificador de tipo automático, que permite al compilador analizar el tipo de expresión por nosotros. Es diferente de los originales que solo corresponden a un especificador de tipo específico (como int). auto permite al compilador realizar la deducción de tipos a través de valores iniciales. Para obtener el tipo de variable definida, la variable definida por auto debe tener un valor inicial. Como sigue:

auto i; // error: declaration of variable 't' with deduced type 'auto' requires an initializer
//因此我们在使用auto时,必须对该变量进行初始化。

auto i= 0; //0为int类型,auto自动推导出int类型
auto j = 2.0; //auto 自动推导出类型为float

int a = 0;
auto b = a; //a 为int类型
auto &c = a; //c为a的引用
auto *d = &a; //d为a的指针
auto i = 1, b = "hello World"; //error: 'auto' deduced as 'int' in declaration of 'i' and deduced as 'const char *' in declaration of 'b'

/* auto 作为成员变量的使用*/
class test_A
{
    
    
public:
    test_A() {
    
    }
    auto a = 0; //error: 'auto' not allowed in non-static class member
    static auto b = 0; //error: non-const static data member must be initialized out of line
    static const auto c = 0;
};

/*c11 中的使用*/
auto func = [&] {
    
    
    cout << "xxx";
}; 
// 不关心lambda表达式究竟是什么类型
auto asyncfunc = std::async(std::launch::async, func);
// 懒得写std::futurexxx等代码

Limitaciones del uso automático

  1. El uso de auto debe inicializarse inmediatamente; de ​​lo contrario, el tipo no se puede derivar
  2. Cuando auto define múltiples variables en una línea, la derivación de cada variable no puede ser ambigua, de lo contrario la compilación fallará
  3. auto no se puede utilizar como parámetro de función
  4. Auto no se puede usar como una variable miembro no estática en la clase
  5. Auto no puede definir matrices, pero punteros
  6. auto no puede deducir los parámetros de la plantilla

Las reglas de derivación del automóvil

  1. Cuando no se declara como referencia o puntero, auto ignorará el tipo de referencia en el lado derecho del signo igual y la calificación constante y volátil.
  2. Cuando se declara como referencia o puntero, auto conservará la referencia en el lado derecho del signo igual y los atributos constante y volátil.
    const int a = 0;
    auto b = a;
    auto &c = a;
    c = 3; 
    //error: cannot assign to variable 'c' with const-qualified type 'const int &'
    //note: variable 'c' declared const here

decltype

decltype se usa para deducir el tipo de expresión, aquí solo se usa para que el compilador analice el tipo de expresión, la expresión no se calculará realmente

int fun(){
    
     return 0; }
decltype(fun()) a;
decltype(fun()) b = 5;

int fun2(int a){
    
     return 0; }
int c = 0;
decltype(fun2(c)) a;
decltype(fun2(c)) b = 5;

Nota : decltype no ignorará las referencias y const, los atributos volátiles como auto, decltype conservarán las referencias de expresión y los atributos const y volátiles

Reglas de inferencia de decltype

Para decltype (exp):

  1. exp es una expresión, decltype (exp) es lo mismo que exp
  2. exp es una llamada de función, decltype (exp) es el mismo que el tipo de valor de retorno de la función
  3. En otros casos, si exp es un lvalue, decltype (exp) es una referencia de lvalue del tipo exp
int a = 0, b = 0;
decltype(a + b) c = 0; // c是int,因为(a+b)返回一个右值
decltype(a += b) d = c;// d是int&,因为(a+=b)返回一个左值

d = 20;
cout << "c " << c << endl; // 输出c 20

La combinación de auto y decltype

Auto y decltype generalmente se usan juntos para derivar el tipo de valor de retorno de la función. Los ejemplos son los siguientes:

template<typename , typename U>
return_value add(T t, U u) {
    
     
    // t和v类型不确定,无法推导出return_value类型
    return t + u;
}

El código anterior se debe a los tipos inciertos de t y u, por lo que, cómo deducir el tipo de valor de retorno, podemos pensar en esto

template<typename T, typename U>
decltype(t + u) add(T t, U u) {
    
     
    // t和u尚未定义
    return t + u;
}

Este código no se puede compilar en C ++ 11, porque cuando se deduce decltype (t + u), t y u no se han definido, compilará el error, por lo que existe el siguiente método llamado postfix de tipo de retorno. :

template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
    
    
    return t + u;
}

La sintaxis de tipo posterior del valor de retorno sirve para resolver el problema de que el tipo de valor de retorno de una función depende del parámetro, pero es difícil determinar el tipo de valor de retorno.

Supongo que te gusta

Origin blog.csdn.net/CFH1021/article/details/106448303
Recomendado
Clasificación