Why do we need the decltype(auto) construct when returning from a function if you can write auto ?

  • I think for compatibility. If your compiler does not support decltype, it is enough to write # define decltype (a), and you will have to replace auto and other types of subtypes. - nick_n_a
  • association: stackoverflow.com/q/24109737/3240681 - αλεχολυτ

2 answers 2

auto is the "decayed" type of expression, i.e. links are lost and copying takes place:

 string& f(); auto x = f(); // тип x - string, ссылка потерялась, строка скопировалась auto g() { return f(); } // возвращается string // аналог в С++11: auto g() -> decay<decltype(f())>::type; 

decltype(expr) is the actual type of expression, no shrinking.
decltype(auto) is a convenient syntax that allows you not to write an expression inside decltype .

 decltype(auto) y = f(); // тип y - string& // аналог в С++11: decltype(f()) y = f(); decltype(auto) h() { return f(); } // возвращается string& // аналог в С++11: auto h() -> decltype(f()); 

In other words, decltype(auto) is a convenient replacement for decltype(expr) ,
and auto is the short syntax for std::decay<decltype(auto)>::type .

    auto

    In C ++ 11, the auto keyword is devoid of its original meaning as a storage class specifier and is now used to implement automatic type inference, provided that an explicit initializer is specified. The compiler sets the type of the variable to the type of the initial value:

     auto maton = 112; // maton получает тип int auto pt = &maton; // pt получает тип int * double fm(double, int); auto pf = fm; // pf получает тип double (*) (double, int) 

    The auto keyword can also simplify template declarations. For example, if il is an object of type std::initializer_list<double> , the following code

     for (std::initializer_list<double>::iterator p = il.begin(); p !=il.end(); p++) 

    You can replace this:

     for (auto p = il.begin(); p != il.end(); p++) 

    decltype

    The decltype keyword creates a type variable that is specified by the expression. The statement below means "assign y to the same type as x", where x is an expression:

     decltype(х) у; 

    Here are a couple of examples:

     double x; int n; decltype(x*n) q; // q получает тот же тип, что и х*n, т.е. double decltype(&x) pd; // pd получает тот же тип, что и &х, т.е. double * 

    This is especially useful in template definitions when the type may not be defined until the creation of a specific instance:

     template<typename Т, typename U) void ef (T t, U u) { decltype(T*U) tu; ... } 

    Tail Return Type

    In C ++ 11, a new syntax for declaring functions has appeared, in which the return type is indicated after the function name and the parameter list, and not before them:

     double f1(double, int); // традиционный синтаксис auto f2(double, int) -> double; // новый синтаксис, // возвращаемым типом является double 

    The new syntax may look less readable than traditional function declarations, but it makes it possible to use decltype to specify return types of template functions:

     template<typename Т, typename U) auto eff (T t, U u) -> decltype (T*U) { } 

    The problem illustrated here is that when the compiler reads the parameter list ef f, T and U are not in scope, so any use of decltype must be after this parameter list. New syntax makes this possible.

    • A question about C ++ 14 and decltype(auto) , and not about C ++ 11. - Abyx
    • Yes, I already understood. Such syntax is hanging for the first time. I will use it conveniently. Thank! - Sergey Tyulenev