You can think of auto
as a placeholder. In your example the declared types of a
and b
are same. The only difference is that auto
is deduced to be the pointer itself in the first case whereas in the second case it is deduced to be just Foo<T>
.
Except for one special case, auto works just like template argument deduction with a function:
template<class U>
void func_a(U);
template<class U>
void func_b(U*);
template<class T> struct Foo {};
template<class T>
void test() {
func_a( new Foo<T> ); // U = Foo<T>*
func_b( new Foo<T> ); // U = Foo<T>
}
In your example auto
is deduced just like the type parameter U
in the above code.
The special case I was talking about are initializer lists:
void test2() {
auto x = {1,2,3}; // OK, decltype(x) --> initializer_list<int>
func_a( {1,2,3} ); // Illegal, U cannot be deduced because
// {1,2,3} is not considered an expression
}
Apart from this special case, the deduction rules are the same.