成员函数SFINAE错误C2938

时间:2015-01-20 10:54:17

标签: c++ visual-c++ sfinae

此代码无法在VS2013中编译。

template<typename T>
class SomeClass {
public:
    std::enable_if_t<std::is_fundamental<T>::value, T>
        DoSomething() {
        return T();
    }

    std::enable_if_t<!std::is_fundamental<T>::value, T>
        DoSomething() {
        return T();
    }
};

如何在VS2013中使其工作(DoSomething必须是非静态成员函数)?

3 个答案:

答案 0 :(得分:2)

SFINAE仅适用于模板。您的DoSomething()不是模板,它是类模板的非模板成员。你需要把它变成一个模板:

template<typename T>
class SomeClass {
public:
    template <class U = T>
    std::enable_if_t<std::is_fundamental<U>::value, T>
        DoSomething() {
        return T();
    }

    template <class U = T>
    std::enable_if_t<!std::is_fundamental<U>::value, T>
        DoSomething() {
        return T();
    }
};

[Live example]

答案 1 :(得分:2)

来自here

  

只有函数类型immediate context中的类型和表达式或其模板参数类型中的失败才是SFINAE错误。

要以DoSomething的分辨率获取SFINAE,您需要通过另一个模板参数引入即时上下文,并检查它是否为T

template<typename T>
class SomeClass {
public:
    template <typename U = T> 
    std::enable_if_t<std::is_fundamental<U>::value && std::is_same<U,T>::value, T>
        DoSomething() {
        return T();
    }

    template <typename U = T> 
    std::enable_if_t<!std::is_fundamental<U>::value && std::is_same<U,T>::value, T>
        DoSomething() {
        return T();
    }
};

添加了std::is_same项检查,以防止有SomeClass::DoSomething<U>UT的类型。

答案 2 :(得分:2)

标签发送比SFINAE更好,更干净:

template<typename T>
class SomeClass {
private:
    T DoSomethingImpl(std::true_type /*is_fundamental*/) { return T(); }
    T DoSomethingImpl(std::false_type /*is_fundamental*/) { return T(); }
public:
    T DoSomething() {
        return DoSomethingImpl(std::is_fundamental<T>());
    }
};