【问题标题】:How to make this boost::enable_if code compile (SFINAE)?如何使这个 boost::enable_if 代码编译(SFINAE)?
【发布时间】:2012-08-19 17:30:46
【问题描述】:

我很困惑为什么下面使用boost::enable_if 的代码无法编译。它检查类型T 是否有成员函数hello,如果是则调用它:

#include <iostream>
#include <boost/utility/enable_if.hpp>
#include <boost/static_assert.hpp>

// Has_hello<T>::value is true if T has a hello function.
template<typename T>
struct has_hello {
  typedef char yes[1];
  typedef char no [2];
  template <typename U> struct type_check;
  template <typename U> static yes &chk(type_check<char[sizeof(&U::hello)]> *);
  template <typename  > static no  &chk(...);
  static const bool value = sizeof(chk<T>(0)) == sizeof(yes);
};

template<typename T>
void doSomething(T const& t,
                 typename boost::enable_if<typename has_hello<T>::value>::type* = 0
                 ) {
  return t.hello();
}

// Would need another doSomething` for types that don't have hello().

struct Foo {
  void hello() const {
    std::cout << "hello" << std::endl;
  }
};

// This check is ok:
BOOST_STATIC_ASSERT(has_hello<Foo>::value);

int main() {
  Foo foo;
  doSomething<Foo>(foo);
}

我来了

no matching function for call to ‘doSomething(Foo&)

gcc 4.4.4.

静态断言没问题,所以has_hello&lt;Foo&gt;::value 确实是true。我是不是用错了boost::enable_if

【问题讨论】:

    标签: c++ boost sfinae enable-if


    【解决方案1】:

    boost::enable_if 的第一个参数必须是 包含名为 value 的静态 bool 常量的类型。您需要的是 enable_if_c 模板(注意 _c 后缀),它采用非类型 bool 参数。

    template<typename T>
    void doSomething(T const& t,
                     typename boost::enable_if_c<has_hello<T>::value>::type* = 0
                     ) {
      return t.hello();
    }
    

    这个compiles and runs很好。

    Paragraph 2 in boost docs.下也有解释

    【讨论】:

    • 啊,谢谢。由于has_hello&lt;T&gt; 是我可以使用typename boost::enable_if&lt; has_hello&lt;T&gt; &gt;::type* = 0 的类型。更好。
    【解决方案2】:

    这里

    typename has_hello<T>::value
    

    has_hello&lt;T&gt;::value 不是类型名称。就是价值。


    不确定bost,但以下工作(gcc 4.7 std=c++0x):

    template<typename T>
    void doSomething(T const& t,
                     typename std::enable_if<has_hello<T>::value>::type* = 0
                     ) {
      return t.hello();
    }
    

    【讨论】:

      【解决方案3】:

      到目前为止,我还没有使用 enable_if,但也许

      typename boost::enable_if<has_hello<T>>::type* = 0
      

      【讨论】:

        猜你喜欢
        • 2015-10-17
        • 2015-05-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多