如何将 SFINAE 与 nullary 成员函数一起使用?

How to use SFINAE with nullary member function?

我有一个带有布尔模板参数 can_fly 的 class 模板 Bird。根据该值,我想启用签名为 void fly();.

的成员函数

这是我的代码:

#include <type_traits>

template<bool can_fly>
class Bird {
public:
    template<typename void_t = typename std::enable_if<can_fly>::type>
    void_t fly() { /* ... */ }
};

int main() {
    Bird<true> flyingBird;
    flyingBird.fly();
    Bird<false> flightlessBird;

    return 0;
}

此代码在 Visual Studio 2015 中编译正常,但 GCC 抱怨“'struct std::enable_if' 中没有名为 'type' 的类型” main.

第三行

我认为 false 案例中没有 ::type 这一事实是 SFINAE 的全部要点。有人可以向我解释我做错了什么以及正确的做法是什么吗?

作为mentioned in this answer:

enable_if works because the substitution of a template argument resulted in an error, and so that substitution is dropped from the overload resolution set and only other viable overloads are considered by the compiler.

在你的例子中没有替代,因为 can_fly 在实例化时是已知的。您可以创建一个 dummy 默认 bool 模板参数来使 SFINAE 正常工作:

template<bool can_fly>
class Bird {
public:
    template<bool X = can_fly, typename = typename std::enable_if<X>::type>
    void fly() { /* ... */ }
};

wandbox example