【发布时间】:2019-01-04 20:52:49
【问题描述】:
我有这段代码可以判断模板类型是否有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 不是总是在编译时评估吗?
【问题讨论】:
-
看起来不像
decltype(has_foo_f<T>())实际上实例化了has_foo_f。我不确定它是否是预期的。直观地说,has_foo_f的返回类型很明显是void,而无需实例化它。如果将返回类型更改为auto,会发生什么?