CTMacUser
CTMacUser

Reputation: 2042

What happens if we use "decltype(auto) f()" as a function declaration with "decltype(f()) result" in the definition?

This is really a C++14 question. And it's more theoretical than practical.

Sometimes you build a function's result in piecemeal:

int f( int x, int y )
{
    int  a;
    //...
    return a;
}

but if you change the return type, you have to change the type of "a" too. I get around this with a special declaration:

int f( int x, int y )
{
    decltype( f(x,y) )  a;
    //...
    return a;
}

(For the newbies: what is the pitfall if a function parameter uses an r-value reference? Hint: we need std::forward to fix it.) A question randomly popped into my head: what if I use the new C++14 feature of "decltype( auto )" as the return type?! Will we get a recursive black hole? Or an error that it's not allowed? Would adding an initializer to "a" make everything all-right?

Upvotes: 1

Views: 198

Answers (1)

dyp
dyp

Reputation: 39121

A question randomly popped into my head: what if I use the new C++14 feature of "decltype( auto )" as the return type?!

The example the OP is referring to is:

auto f( int x, int y ) // using C++1y's return type deduction
{
    decltype( f(x,y) )  a;
    //...
    return a;
}

Will we get a recursive black hole? Or an error that it's not allowed?

It's not allowed [dcl.spec.auto]/11:

If the type of an entity with an undeduced placeholder type is needed to determine the type of an expression, the program is ill-formed. Once a return statement has been seen in a function, however, the return type deduced from that statement can be used in the rest of the function, including in other return statements.


Would adding an initializer to a make everything all-right?

Ex.

decltype( f(x,y) )  a = 42;

No; the use of decltype requires determining the return type of f. However, the following is possible:

auto a = 42;

From a comment:

so I could have a quick-and-dirty if & return block at the beginning of the function, then use the decltype(f(X)) construct afterwards (for the rest of the function)?

Yes, e.g.

auto f( int x, int y ) // using C++1y's return type deduction
{
    if(false) return int();

    decltype( f(x,y) )  a;
    //...
    return a;
}

However, I'd prefer either:

auto f( int x, int y ) // using C++1y's return type deduction
{
    int a; // specifying the return type of `f` here
    //...
    return a;
}

or

auto f( int x, int y ) // using C++1y's return type deduction
{
    auto a = 42; // specifying the return type of `f` via the initializer
    //...
    return a;
}

Upvotes: 2

Related Questions