Boost logo

Boost :

From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2007-03-30 19:06:26


On 3/30/07, Daniel Walker <daniel.j.walker_at_[hidden]> wrote:
> On 3/30/07, Guillaume Melquiond <guillaume.melquiond_at_[hidden]> wrote:
> > Quoting Daniel Walker:
> > > OK, thanks for the help. I was trying to simplify my code to replicate
> > > the error I'm getting, and I may have gone to far. Can you tell me if
> > > the following contains a substitution?
> >
> > > 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!

I spoke too soon.

Your suggestion got ride of the compilation error but now the overload
resolution always selects f(W*, ...), even when the template does
exist with the correct number of args. Here's an example that will
accept the member templates correctly and reject member templates that
have the wrong name. But if the names match and the parameters don't
the compilation error comes back again.

struct foo {
   template<class U, class V> struct xxx;
};

struct bar {
   template<class U, class V> struct yyy;
};

struct baz {
   template<class U> struct xxx;
};

typedef char (&yes)[1];
typedef char (&no) [2];

template<class T, class U, class V>
struct has_xxx {
   static no f(...) {}

   template<class W>
   static yes f(W*, typename W::template xxx<U,V>* = 0) {}

   static const bool value = sizeof(f((T*)0)) == sizeof(yes);
   // error: wrong number of template arguments (2, should be 1)
   // provided for `template<class U> struct baz::xxx'
};

int main()
{
  int assert[has_xxx<foo, int, int>::value];
  int assert_not_yyy[!has_xxx<bar, int, int>::value];
  int assert_not_biary[!has_xxx<baz, int, int>::value]; // comment out
to remove error
}

gcc and msvc both have problems with this but apparently for different
reasons. It seems like there's a consensus that SFINAE should allow
this code to compile on a standard compliant compiler. I'm going to
contact the gcc folks at least to try to get more info. I'll write
test cases for this, but exclude them from the latest gcc and msvc.
Let me know if I'm misunderstanding something and please let me know
if you find a work around for this problem.

Thanks,
Daniel


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