Still fighting with templates. In this example, despite the fact that is copied straight from a book I'm getting the following error message: Error 2 error C2784: 'IsClassT<T>::One IsClassT<T>::test(int C::* )' : could not deduce template argument for 'int C::* ' from 'int'.
This is an example from a book Templates - The Complete Guide. (I work with Visual Studio 2010 RC).
template<typename T>
class IsClassT {
private:
typedef char One;
typedef struct { char a[2]; } Two;
template<typename C> static One test(int C::*);
template<typename C> static Two test(…);
public:
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
enum { No = !Yes };
};
class MyClass {
};
struct MyStruct {
};
union MyUnion {
};
void myfunc()
{
}
enum E {e1} e;
// check by passing type as template argument
template <typename T>
void check()
{
if (IsClassT<T>::Yes) {
std::cout << " IsClassT " << std::endl;
}
else {
std::cout << " !IsClassT " << std::endl;
}
}
// check by passing type as function call argument
template <typename T>
void checkT (T)
{
check<T>();
}
int main()
{
/*std::cout << "int: ";
check<int>(); */
std::cout << "MyClass: ";
check<MyClass>();
}
And although I know roughly what's going on in this example I cannot fix this error开发者_如何学编程.
Thanks for help.My compiler (MSVC2008TS) likes it if you don't fully qualify the test
expression:
enum { Yes = sizeof(test<T>(0)) == 1 };
But is this even legal code?
Shouldn't this line
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
be
enum { Yes = sizeof(IsClassT<T>::template test<T>(0)) == 1 };
instead?`
(And because I'm anal, I'd write sizeof(IsClassT<T>::template test<T>(0)) == sizeof(One)
.)
Not exactly an answer to this question, but rather a different approach to your problem. I find it easier to do SFINAE tests in specializations rather than in functions defined in that template:
// used to pass a type tested with SFINAE
template<typename T> struct tovoid { typedef void type; };
Using it to pass a type that may be invalid:
template<typename T, typename U = void>
struct is_class {
static bool const value = false;
};
// if "int T::*" is a valid type, this specialization is used
template<typename T>
struct is_class<T, typename tovoid<int T::*>::type> {
static bool const value = true;
};
This way it's considerably shorter and the noise with sizeof
and things aren't done.
精彩评论