我已经编写了以下代码,它根据GCC 4.7和MSVC 2013编译并按预期工作,但无法在MSVC 2012下编译:
#include <iostream>
template<typename TClass>
struct IsLoadableHelper {
template<typename T, T t> struct Helper {};
struct Mixin1 {
void Load(std::istream*);
};
struct MixedStruct1 : public Mixin1, public TClass {};
// template<typename U>
// static char f(Helper<void(TClass::*)(std::istream*), &TClass::Load>*);
template<typename U>
static long f(Helper<void(Mixin1::*)(std::istream*), &U::Load>*);
template<typename U>
static char f(...);
enum { value = sizeof(f<MixedStruct1>(0)) == sizeof(char) };
};
struct Loadable
{
void Load(std::istream*);
};
struct DerivedLoadable : Loadable
{};
struct NotLoadable
{
};
int main(void)
{
std::cout << IsLoadableHelper<NotLoadable>::value << std::endl;
std::cout << IsLoadableHelper<Loadable>::value << std::endl;
std::cout << IsLoadableHelper<DerivedLoadable>::value << std::endl;
return 0;
}
#include "stdafx.h"
#include <iostream>
template<typename TClass>
struct IsLoadableHelper {
template<typename T, T t> struct Helper {};
struct Mixin1 {
void Load(std::istream*);
};
struct MixedStruct1 : public Mixin1, public TClass {};
template<typename U>
static long f(Helper<void(Mixin1::*)(std::istream*), &U::Load>*);
template<typename U>
static char f(...);
enum { value = sizeof(f<MixedStruct1>(0)) == sizeof(char) };
};
struct Loadable
{
void Load(std::istream*);
};
struct NotLoadable
{
};
int main(void)
{
std::cout << IsLoadableHelper<NotLoadable>::value << std::endl;
std::cout << IsLoadableHelper<Loadable>::value << std::endl;
return 0;
}
在MSVC 2012下编译期间,它返回以下错误:
1>Source.cpp(22): error C3867: 'IsLoadableHelper<TClass>::Mixin1::Load': function call missing argument list; use '&IsLoadableHelper<TClass>::Mixin1::Load' to create a pointer to member
1> with
1> [
1> TClass=Loadable
1> ]
1> Source.cpp(43) : see reference to class template instantiation 'IsLoadableHelper<TClass>' being compiled
1> with
1> [
1> TClass=Loadable
1> ]
1>Source.cpp(22): error C3867: 'IsLoadableHelper<TClass>::Mixin1::Load': function call missing argument list; use '&IsLoadableHelper<TClass>::Mixin1::Load' to create a pointer to member
1> with
1> [
1> TClass=DerivedLoadable
1> ]
1> Source.cpp(44) : see reference to class template instantiation 'IsLoadableHelper<TClass>' being compiled
1> with
1> [
1> TClass=DerivedLoadable
1> ]
我看到它无法解析指向Load函数的指针,并建议我获取指向基类的指针。这是预料之中的。但它报告错误而不是跟随SFINAE而只是继续,这是意料之外的。我只能使用C ++ 03,我需要在Visual Studio 2012 Update 4下使这段代码工作。如何解决?
答案 0 :(得分:0)
如何更简单的替代方案:
template<typename TClass>
struct IsLoadableHelper {
template<typename T, T> struct Helper;
template<typename U>
static long f(Helper<void (U::*)(std::istream*), &U::Load>*);
template<typename U>
static char f(...);
enum { value = sizeof(f<TClass>(0)) == sizeof(char) };
};
这会满足MSVC2012吗? MSVC2013很高兴!