我很困惑为什么以下使用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<Foo>::value
确实是true
。我使用boost::enable_if
错了吗?
答案 0 :(得分:4)
boost::enable_if
的第一个参数必须是类型,其中包含名为bool
的静态value
常量。您需要的是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();
}
下解释
答案 1 :(得分:3)
下面
typename has_hello<T>::value
has_hello<T>::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();
}
答案 2 :(得分:2)
到目前为止,我还没有使用enable_if,但可能
typename boost::enable_if<has_hello<T>>::type* = 0