Search code examples
c++templateslanguage-lawyerc++17template-argument-deduction

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


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.


Solution

  • 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.