我有这段代码来确定模板类型是否具有foo():
template <typename T, typename = void>
struct has_foo : std::false_type {};
template <typename T>
struct has_foo<T, std::void_t<decltype(std::declval<T&>().foo()) > > : std::true_type {};
template <typename T>
void has_foo_f(){
static_assert(has_foo<T>::value, "Type does not have foo().");
}
然后,我有了bar
函数,该函数采用foo
作为模板参数:
template<typename T, typename = decltype(has_foo_f<T>())>
void bar(){}
在主文件中,我有一个失败案例:
//Foo does not implement foo(). It should fail!
template<typename T>
class Foo{};
int main()
{
has_foo_f<Foo<int>>(); //This line fail
bar<Foo<int>>(); //This line does not fail
}
当我直接调用has_foo_f
时,编译器给了我静态声明错误,这是正确的。
但是,当我调用bar<Foo<int>>
时,编译器成功地编译了它而没有错误。
为什么会这样?为什么不评估static_assert?我了解decltype
不需要评估static_assert
即可获取类型信息,但是static_assert
并非总是在编译时进行评估吗?
答案 0 :(得分:2)
操作数不会求值,因此,当在需要函数定义存在的上下文中引用特殊化时,在实例化函数模板时就不需要函数定义存在(或返回类型完整)。因此,您需要实例化功能模板以检查功能体内是否发生:
'.'