The most obvious answer could be - because the standard says so.
That's fine, but I'm wrapping my head around it to understand the reasons behind this choice.
Consider the following example:
template<typename T>
struct S { S(T) {} };
S f() { return 0; }
int main() {
auto s = f();
(void)s;
}
It fails to compile with errors like:
error: use of class template 'S' requires template arguments; argument deduction not allowed in function return type
Quite easy to fix, it isn't a problem, something like this works just fine:
auto f() { return S{0}; }
However, I'd like to understand what were the drawbacks of allowing class template arguments deduction also in function return types.
At a first glance, it looks just like a silly limitation, but I'm pretty sure I'm missing something important here.
Because the standard says so.
You could ask the question: why is there a difference between these lines of code:
You could come up with a handwavy explanation of why the first one should be okay and why the second one should not be - but fundamentally class template argument deduction was proposed to only address the first case and not the second. The first one is okay because the standard says so, and the second one is an error because the standard says so.
There is an extension proposed (P1021, under "Return type deduction for functions") that would address the second case. Whether or not you think this is a good idea... ¯\_(ツ)_/¯
Just my hand-wavy two cents that summarize my understanding:
In
the
S
is no type that could be deduced, its just a template. You could writebut now it is obvious that for a call
there is no way to deduce what type
T
is supposed to be.There's nothing language-lawery here: If you specify a return type (and not
auto
orT
whereT
is a template type), that return type has to be valid. let me give you even a simpler, better example:Obviously it fails to compile, even without fancy templates,
auto
and type deductions, becausestd::vector
isn't a type,std::vector<int>
is.When you specify
S
as a return type you basicallyS
isn't a type,S<int>
is.