
On 3/30/07, Ames Andreas <Andreas.Ames@comergo.com> wrote:
On 3/30/07, Guillaume Melquiond <guillaume.melquiond@ens-lyon.fr> 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