|
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