在MSVC2012中检查声明的成员函数

时间:2014-11-26 10:20:09

标签: c++ visual-studio-2012 sfinae c++03

我已经编写了以下代码,它根据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下使这段代码工作。如何解决?

1 个答案:

答案 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很高兴!