
On Fri, Apr 9, 2010 at 4:09 PM, Eric Niebler <eric@boostpro.com> wrote:
On 4/8/2010 1:53 PM, Daniel Walker wrote:
On Thu, Apr 8, 2010 at 2:18 PM, Eric Niebler <eric@boostpro.com> wrote:
7.1.6.2/4: "The type denoted by decltype(e) is defined as follows: — if e is ... or if e names a set of overloaded functions, the program is ill-formed;"
<snip>
If overload resolution succeeds then e names a statically chosen function not an overload set. If overload resolution fails then e names an overload set and the program is ill-formed. That's my understanding at least. So, yes, you can use decltype on an overloaded function and the program is not ill-formed, so long as overload resolution succeeds. I believe that's true of call expressions in any context.
Daniel, you're probably right. Thanks for the clarification. I think Steven is right though that if you use an incomplete type in a function call expression (a possibly overloaded function set), then the program is ill-formed if any signature in the function set requires a complete type. This can happen in any context, decltype or not, so I don't think it has bearing on this discussion.
Yes, and I like the way you put that, focusing on the requirement of the signature. That clarifies things. The type could be incomplete in the context of the signature, but it must be complete in the context of the call expression. With decltype those context could overlap, which is something new to think about. So, yeah, in general, if some signature requires a type to be complete, then the function can't be used in context where the type is incomplete... But I can think of one counterexample. If SFINAE drops the signature during template substitution, then overload resolution could still succeed. So the following, I believe, is valid even though S is incomplete. g++ accepts it. template<class T> int f(typename T::foo, T x = T()); template<class T> int f(...); struct S; typedef decltype(f<S>(0)) type; Daniel Walker