I'm writing some code where the return type of a function is rather complicated. I'd like to make use of auto
for deducing from the return type, but that's obviously not possible in a forward declaration. So I was hoping to at least only duplicate the contents of the return statement and do the following,
int q = 5; // veeery complicated type
/* Declaration - the best we can do */
auto f() -> decltype(q);
/* Later, in a different file */
auto f() {
return q;
}
This produces the following error in GCC 7,
error: ambiguating new declaration of ‘auto f()’
note: old declaration ‘int f()’
Of course I could repeat
auto f() -> decltype(q) {
return q;
}
in the definition (which works) but why should I need to when the return type is already uniquely given by the return
statement? How is the type of f
in my definition ultimately any more ambiguous than int f()
?
The trailing return type feature removes a C++ limitation where the return type of a function template cannot be generalized if the return type depends on the types of the function arguments.
In C++14, you can just use auto as a return type.
Use auto and decltype to declare a function template whose return type depends on the types of its template arguments. Or, use auto and decltype to declare a function template that wraps a call to another function, and then returns the return type of the wrapped function.
Like pointers, we can also use auto to declare references to other variables.
The problem here is that a trailing return is not the same as purely deduced return type. In [dcl.spec.auto]/2
[...]If the function declarator includes a trailing-return-type (8.3.5), that specifies the declared return type of the function
So
auto f() -> decltype(q);
is really
int f();
which is different from
auto f()
There is also [dcl.spec.auto]/13
Redeclarations or specializations of a function or function template with a declared return type that uses a placeholder type shall also use that placeholder, not a deduced type. [ Example:
auto f(); auto f() { return 42; } // return type is int auto f(); // OK int f(); // error, cannot be overloaded with auto f() decltype(auto) f(); // error, auto and decltype(auto) don’t match
Which is kind of opposite of what is going on here but it does further exemplify that this is not allowed
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With