|
Boost : |
Subject: Re: [boost] decltype and incomplete types
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2010-04-09 17:39:18
On Fri, Apr 9, 2010 at 4:09 PM, Eric Niebler <eric_at_[hidden]> wrote:
> On 4/8/2010 1:53 PM, Daniel Walker wrote:
>> On Thu, Apr 8, 2010 at 2:18 PM, Eric Niebler <eric_at_[hidden]> 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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk