SFINAE and decltype(auto)
Asked Answered
L

2

20

If a function template returns decltype(auto) (or another type specifier using auto) but the return statement would be ill-formed, does SFINAE result? Is the return statement considered to be the immediate context of the function signature?

Nothing in the N3690 draft seems to require this. By default, I guess SFINAE does not apply.

This seems unfortunate because you can write a function to forward to another function, but you cannot make its existence conditional on the delegate as when writing longhand. Furthermore, checking the existence of a peer nonstatic member function cannot be done without decltype(auto) because this cannot be used in a function signature. However this indicates a fundamental problem, as decltype(auto) provides a path to considering the class type as complete within a member signature, where it's not.

Has a proposal been written, or has the problem been formally analyzed anywhere?

The ability to treat the class type as complete within a member signature may have other implications… but that's just fodder for another question.

Luhe answered 12/7, 2013 at 6:23 Comment(5)
I had been wondering exactly this. Sadly, I've also been too lazy to follow 1y proposals...Informative
@MarkGarcia Yes, that's a given. I just added a note to the end of the question; non-template members may still possibly open a wormhole to the twilight zone.Luhe
If there were some examples in the question, it would have been easier to understand for the stupids like me. :)Mccahill
A little example would go a long way to make the question more clear. Perhaps there are other ways to achieve what you want.Elongation
@n.m. There are always more ways. I'm not stuck, but I am trying to avoid having 8 repetitive overloads. The answer I'm looking for is a pointer into a proposal paper, so I can tell whether to write a report myself.Luhe
C
17

but the return statement would be ill-formed, does SFINAE result?

The proposal-n3638 says,

SFINAE

Since the return type is deduced by instantiating the template, if the instantiation is ill-formed, this causes an error rather than a substitution failure. This allows an auto function to return a lambda, which is not possible using the decltype(returned expression) pattern.

Hope that is what you're looking for.

Cattery answered 12/7, 2013 at 6:41 Comment(1)
Bingo! Precisely what I was looking for. I need to go for now but I'll read that later to figure out how they reconcile member instantiation with incomplete type.Luhe
L
4

Following up on Nawaz's link, the remaining questions are answered by N3690 §7.1.6.4/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.

This means that even if SFINAE worked with return type deduction, it couldn't be used to query one function declaration from another. The signature is essentially invalid until the return statement is processed, which occurs at the closing brace of the class {} definition, and after the definitions of preceding members have been processed.

In a sense, all member decltype(auto) functions are incomplete with respect to preceding functions in the same class:

struct s {
    void f() { a(); } // error: use of ‘auto s::a()’ before deduction of ‘auto’
    auto a() { return 3; }
};

This is GCC's complaint; it goes away if the member declarations are reversed. This is because the function definitions are processed in order of declaration, when the } from the class definition is reached. If the statement a(); is processed before the return 3;, then the program is ill-formed.

Luhe answered 12/7, 2013 at 13:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.