如何将 SFINAE 与空成员函数一起使用? [英] How to use SFINAE with nullary member function?

查看:64
本文介绍了如何将 SFINAE 与空成员函数一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有布尔模板参数 can_fly 的类模板 Bird.根据该值,我想启用具有签名 void fly(); 的成员函数.

I have a class template Bird with a Boolean template parameter can_fly. Depending on that value, I want to enable a member function with the signature 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 抱怨 main 的第三行中在 'struct std::enable_if' 中没有名为 'type' 的类型".

This code compiles fine in Visual Studio 2015, but GCC complains that there is "no type named 'type' in 'struct std::enable_if'" in the third line of main.

我认为在 false 情况下没有 ::type 的事实是 SFINAE 的全部意义所在.有人可以向我解释我做错了什么以及正确的方法是什么吗?

I thought the fact that there is no ::type in the false case was the entire point of SFINAE. Can somebody explain to me what I did wrong and what the correct approach is?

推荐答案

As 在本回答中提到:

enable_if 起作用是因为模板参数的替换导致错误,因此替换从重载决议集中被删除,编译器只考虑其他可行的重载.

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 正常工作:

In your case there is no substitution because can_fly is known at the moment of instantiation. You can create a dummy default bool template parameter to make SFINAE work properly:

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

魔杖盒示例

这篇关于如何将 SFINAE 与空成员函数一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆