decltype vs auto

C++Type Inference

C++ Problem Overview


As I understand it, both decltype and auto will attempt to figure out what the type of something is.

If we define:

int foo () {
	return 34;
}

Then both declarations are legal:

auto x = foo();
cout << x << endl;

decltype(foo()) y = 13;
cout << y << endl;

Could you please tell me what the main difference between decltype and auto is?

C++ Solutions


Solution 1 - C++

decltype gives the declared type of the expression that is passed to it. auto does the same thing as template type deduction. So, for example, if you have a function that returns a reference, auto will still be a value (you need auto& to get a reference), but decltype will be exactly the type of the return value.

#include <iostream>
int global{};
int& foo()
{
   return global;
}
 
int main()
{
    decltype(foo()) a = foo(); //a is an `int&`
    auto b = foo(); //b is an `int`
    b = 2;
    
    std::cout << "a: " << a << '\n'; //prints "a: 0"
    std::cout << "b: " << b << '\n'; //prints "b: 2"
    
    std::cout << "---\n";
    decltype(foo()) c = foo(); //c is an `int&`
    c = 10;
    
    std::cout << "a: " << a << '\n'; //prints "a: 10"
    std::cout << "b: " << b << '\n'; //prints "b: 2"
    std::cout << "c: " << c << '\n'; //prints "c: 10"
 }

Also see David Rodríguez's answer about the places in which only one of auto or decltype are possible.

Solution 2 - C++

auto (in the context where it infers a type) is limited to defining the type of a variable for which there is an initializer. decltype is a broader construct that, at the cost of extra information, will infer the type of an expression.

In the cases where auto can be used, it is more concise than decltype, as you don't need to provide the expression from which the type will be inferred.

auto x = foo();                           // more concise than `decltype(foo()) x`
std::vector<decltype(foo())> v{ foo() };  // cannot use `auto`

The keyword auto is also used in a completely unrelated context, when using trailing return types for functions:

auto foo() -> int;

There auto is only a leader so that the compiler knows that this is a declaration with a trailing return type. While the example above can be trivially converted to old style, in generic programming it is useful:

template <typename T, typename U>
auto sum( T t, U u ) -> decltype(t+u)

Note that in this case, auto cannot be used to define the return type.

Solution 3 - C++

modify @Mankarse's example code,I think a better one blew:

#include <iostream>
int global = 0;
int& foo()
{
   return global;
}

int main()
{
    decltype(foo()) a = foo(); //a is an `int&`
    auto b = foo(); //b is an `int`
    b = 2;

    std::cout << "a: " << a << '\n'; //prints "a: 0"
    std::cout << "b: " << b << '\n'; //prints "b: 2"
    std::cout << "global: " << global << '\n'; //prints "global: 0"

    std::cout << "---\n";
    
    //a is an `int&`
    a = 10;

    std::cout << "a: " << a << '\n'; //prints "a: 10"
    std::cout << "b: " << b << '\n'; //prints "b: 2"
    std::cout << "global: " << global << '\n'; //prints "global: 10"

    return 0;

}

Solution 4 - C++

Generally, if you need a type for a variable you are going to initialize, use auto. decltype is better used when you need the type for something that is not a variable, like a return type.

Solution 5 - C++

> I consider auto to be a purely simplifying feature whereas the primary purpose of decltype is to enable sophisticated metaprogramming in foundation libraries. They are however very closely related when looked at from a language-technical point of use.

From HOPL20 4.2.1, Bjarne Stroustrup.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJames LeonardView Question on Stackoverflow
Solution 1 - C++MankarseView Answer on Stackoverflow
Solution 2 - C++David Rodríguez - dribeasView Answer on Stackoverflow
Solution 3 - C++J.DoeView Answer on Stackoverflow
Solution 4 - C++AnkurView Answer on Stackoverflow
Solution 5 - C++Yaokun XuView Answer on Stackoverflow