Why isn't argument deduction allowed in function return type?

青春壹個敷衍的年華 提交于 2020-02-01 04:12:05

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!