如何使用布尔模板参数启用成员函数?

时间:2017-12-22 03:29:12

标签: c++ templates sfinae

我希望一个类有两个不同的Option 1实现,并根据布尔模板参数进行选择。我尝试使用this answer中描述的SFINAE原则,如下所示:

push

但是,我收到的错误是&#34;无法在类范围内专门化一个函数template<class T, bool foo=true> class Bar { template <> typename std::enable_if<foo>::type push(const T& value) { /* one implementation */} template <> typename std::enable_if<!foo>::type push(const T& value) { /* another implementation */ } } &#34;在gcc下,我不明白为什么。虽然我的代码与链接答案中的代码不完全相同,但它似乎非常相似,我无法发现关键区别。

我也尝试使用类似于this answer中建议的语法,但它也不起作用(错误是&#34;类成员不能重新声明&#34;相反):

push

我该如何做到这一点?

2 个答案:

答案 0 :(得分:3)

首先,SFINAE适用于函数模板重载;所以你应该采用第二种方法。但是你声明了两个具有相同签名的重载;请注意,template参数的默认参数不属于签名。

将其更改为

template <bool enable=foo>
typename std::enable_if<enable>::type
//                      ~~~~~~
push(const T& value) { /* one implementation */}

template <bool enable=foo>
typename std::enable_if<!enable>::type
//                      ~~~~~~~
push(const T& value) { /* another implementation */ } 

答案 1 :(得分:2)

作为替代方案:

    C ++ 17中的
  • if constexpr

    template<class T, bool foo=true>
    class Bar {
    public:
        void push(const T& value) {
            if constexpr(foo) {
                /* one implementation */
            } else {
                /* another implementation */
            }
        }
    };
    
  • 标签调度:

    template<class T, bool foo=true>
    class Bar {
        void push_impl(const T& value, std::true_type) {
            /* one implementation */
        } 
        void push_impl(const T& value, std::false_type) {
            /* another implementation */
        }
    
    public:
        void push(const T& value) {
            push_impl(value, std::integral_constant<bool, foo>{});
        }
    };