在模板参数中未评估static_assert

时间:2019-01-04 20:52:50

标签: c++ templates

我有这段代码来确定模板类型是否具有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并非总是在编译时进行评估吗?

1 个答案:

答案 0 :(得分:2)

{p}的

操作数不会求值,因此,当在需要函数定义存在的上下文中引用特殊化时,在实例化函数模板时就不需要函数定义存在(或返回类型完整)。因此,您需要实例化功能模板以检查功能体内是否发生:

'.'