I'm writing some code where the return type of a function is rather complicated. I'd like to make use of
auto
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;
}
error: ambiguating new declaration of ‘auto f()’
note: old declaration ‘int f()’
auto f() -> decltype(q) {
return q;
}
return
f
int f()
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