The use of C++11 auto and decltype

auto

In C++ programming, it is often necessary to assign the value of an expression to a variable, and it is necessary to clearly know what type the variable is when declaring the variable. However, this is not so easy to do, and sometimes it is not possible at all. In order to solve this problem, the new C++11 standard introduced the auto type specifier, which allows the compiler to analyze the type of the expression for us. It is different from the original ones that only correspond to a specific type specifier (such as int). auto allows the compiler to perform type deduction through initial values. In order to obtain the type of the defined variable, so the variable defined by auto must have an initial value. As follows:

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等代码

Limitations of auto use

  1. The use of auto must be initialized immediately, otherwise the type cannot be derived
  2. When auto defines multiple variables in one line, the derivation of each variable cannot be ambiguous, otherwise the compilation will fail
  3. auto cannot be used as a function parameter
  4. Auto cannot be used as a non-static member variable in the class
  5. Auto cannot define arrays, but pointers
  6. auto cannot deduce template parameters

The derivation rules of auto

  1. When not declared as a reference or pointer, auto will ignore the reference type on the right side of the equal sign and const and volatile qualification
  2. When declared as a reference or pointer, auto will retain the reference on the right side of the equal sign and the const and volatile attributes
    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 is used to deduce the expression type, here it is only used for the compiler to analyze the type of the expression, the expression will not actually be calculated

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;

Note : decltype will not ignore references and const and volatile attributes like auto, decltype will retain the references and const and volatile attributes of expressions

The derivation rules of decltype

For decltype(exp):

  1. exp is an expression, decltype(exp) is the same as exp
  2. exp is a function call, decltype(exp) is the same as the return value type of the function
  3. In other cases, if exp is an lvalue, decltype(exp) is an lvalue reference of exp type
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

The combination of auto and decltype

Auto and decltype are generally used together to derive the type of function return value. Examples are as follows:

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

The above code is due to the uncertain types of t and u, so how to deduce the return value type, we may think of this

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

This code cannot be compiled on C++11, because when decltype(t +u) is deduced, t and u have not been defined, it will compile error, so there is the following method called return type postfix. :

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

The post-type syntax of the return value is to solve the problem that the return value type of a function depends on the parameter but it is difficult to determine the return value type.

Guess you like

Origin blog.csdn.net/CFH1021/article/details/106448303