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

Jon*_*ton 4 c++ templates sfinae

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

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 */ } 
}
Run Code Online (Sandbox Code Playgroud)

但是,我push在 gcc 下收到“无法专门化类范围内的函数”的错误,我不明白为什么。尽管我的代码与链接答案中的代码不完全一样,但它似乎非常相似,我无法发现关键区别。

我还尝试使用与此答案中建议的语法类似的语法,但它也不起作用(错误是“不能重新声明类成员”):

  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 */ } 
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

son*_*yao 5

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

将其更改为

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 */ } 
Run Code Online (Sandbox Code Playgroud)