问题
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.
回答1:
There's nothing language-lawery here: If you specify a return type (and not auto
or T
where T
is a template type), that return type has to be valid. let me give you even a simpler, better example:
std::vector function() {
return std::vector<int>();
}
Obviously it fails to compile, even without fancy templates, auto
and type deductions, because std::vector
isn't a type, std::vector<int>
is.
When you specify S
as a return type you basically
- Prevent the compiler from deducing the type itself
- Specify an invalid return type, as
S
isn't a type,S<int>
is.
回答2:
Why isn't argument deduction allowed in function return type?
Because the standard says so.
You could ask the question: why is there a difference between these lines of code:
S s = 0; // OK
S s() { return 0; } // error - even though this is also copy-initializing an "S" from 0
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... ¯\_(ツ)_/¯
回答3:
Just my hand-wavy two cents that summarize my understanding:
In
S f() { return 0; }
the S
is no type that could be deduced, its just a template. You could write
template<typename T>
S<T> f() { return 0;}
but now it is obvious that for a call
auto s = f();
there is no way to deduce what type T
is supposed to be.
来源:https://stackoverflow.com/questions/50622302/why-isnt-argument-deduction-allowed-in-function-return-type