Boost logo

Boost :

From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2007-03-30 14:44:56


On 3/30/07, Ames Andreas <Andreas.Ames_at_[hidden]> wrote:
> >
> > On 3/30/07, Guillaume Melquiond
> > <guillaume.melquiond_at_[hidden]> wrote:
> > > Quoting Daniel Walker:
> > > > static const int size = sizeof(f<T>(0, 0));
> > >
> > > At first sight, I would have said that it does. But on
> > further reflexion, it
> > > probably does not, as there is no deduction from the argument types.
> > > But if you
> > > use f((T*)0,0) instead, then it should work.
> >
> > Your right. Excellent!
> >
> > This doesn't work on MSVC 8.0, however. I believe it doesn't work
> > using template-based SFINAE on MSVC as well. If I can't work around
> > it, would it be ok if I exclude MSVC from tests for has_template_xxx
> > rejecting types containing member templates with the correct name but
> > incorrect arguments? Everything else works on VC 8.0 and VC 7.1. If
> > the bug is fixed in MSVC or if someone else comes up with a work
> > around, we can then include MSVC in these tests.
>
> After rereading 14.8.2 [temp.deduct] I'd say, both forms are compliant. Rejecting one (with explicit template arguments) and accepting the other should definitely be a bug. At least, I can't see how both forms would differ regarding SFINAE.

I was testing with gcc 4.1.2. So, you're saying in the above example
it should accept both of the following:

static const int size = sizeof(f<T>(0, 0));
static const int size = sizeof(f((T*)0,0));

That was my first impression as well, but I wasn't sure if they'd be
equivalent or not. I may try to send the gcc folks a bug report and
see what they think. At least there's one way to get gcc to accept it.

How should SFINAE applied to user-defined class template
specializations work? The following is close to the has_xxx
implementation for VC8.

typedef void sfinae_select_tag;
template<class T>
struct sfinae_selector {
    typedef sfinae_select_tag type;
};

template<class T, class T0, class T1, class U = sfinae_select_tag>
struct has_bar_impl {
    static const bool value = false;
};

template<class T, class T0, class T1>
struct has_bar_impl<
    T, T0, T1
  , typename sfinae_selector<
        typename T::template bar<T0, T1>
>::type
> {
    static const bool value = true;
};

template<class T, class T0, class T1>
struct has_bar
    : has_bar_impl<T, T0, T1> {};
     //error: wrong number of template arguments (2, should be 1)
     //provided for `template<class U> struct foo::bar'

struct foo {
   template<class U> struct bar;
};

int main()
{
   has_bar<foo, int, int>::value;
}

Should this work according to the standard? Anyone have ideas for
coercing msvc into not issuing a compilation error in this case?

Thanks!
Daniel


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk