The Vee The Vee - 3 years ago 151
C++ Question

Clash between trailing return type and return type deduction

I'm writing some code where the return type of a function is rather complicated. I'd like to make use of

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
statement? How is the type of
in my definition ultimately any more ambiguous than
int f()

Answer Source

The problem here is that a trailing return is not the same as purely deduced return type. In []/2

[...]If the function declarator includes a trailing-return-type (8.3.5), that specifies the declared return type of the function


auto f() -> decltype(q);

is really

int f();

which is different from

auto f()

There is also []/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

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download