Problem with SFINAE canAdd Template

I am trying to tow using the SFINAE template to determine if two classes can be added. This is mainly for a better understanding of how SFINAE works, and not for any specific "real world" reason.

So what I came up with

#include <assert.h> struct Vec { Vec operator+(Vec v ); }; template<typename T1, typename T2> struct CanBeAdded { struct One { char _[1]; }; struct Two { char _[2]; }; template<typename W> static W make(); template<int i> struct force_int { typedef void* T; }; static One test_sfinae( typename force_int< sizeof( make<T1>() + make<T2>() ) >::T ); static Two test_sfinae( ... ); enum { value = sizeof( test_sfinae( NULL ) )==1 }; }; int main() { assert((CanBeAdded<int, int>::value)); assert((CanBeAdded<int, char*>::value)); assert((CanBeAdded<char*, int>::value)); assert((CanBeAdded<Vec, Vec>::value)); assert((CanBeAdded<char*, int*>::value)); } 

This is a compilation for everyone but the last line, which gives

 finae_test.cpp: In instantiation of 'CanBeAdded<char*, int*>': sfinae_test.cpp:76: instantiated from here sfinae_test.cpp:40: error: invalid operands of types 'char*' and 'int*' to binary 'operator+' 

So, this error refers to what I would expect, but I would expect the compiler to then find the definition of test_sfinae (...) and use it instead (and will not complain about the one that is not parsing.

It’s clear that I’m missing something, I just don’t know what it is.

+4
source share
1 answer

It seems to me that you are faced with a problem that was discussed in Core Issue 339 , as well as N2634 . The bottom line is that you click a little higher than what any compiler can handle, although what you do is allowed by the standard. C ++ 0x will add more details about what will and will not cause SFINAE to crash compared to a hard bug. See N3000 , Β§14.9.2 if you want to get into gory details.

+4
source

All Articles