【问题标题】:Checking declared member function in MSVC2012检查 MSVC2012 中声明的成员函数
【发布时间】:2014-11-26 10:20:08
【问题描述】:

我编写了以下代码,它在 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 下工作。如何修复它?

【问题讨论】:

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


    【解决方案1】:

    来个更简单的替代方案怎么样:

    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 很开心!

    【讨论】:

    • 看起来如果有 Base::Load(istream*) 而没有 Derived::Load(istream*) 的情况下它不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    • 2012-11-21
    • 1970-01-01
    相关资源
    最近更新 更多