我试图确定在编译时,如果一个特定的类型是类型std::pair.当我编译下面的代码时,我在两个分支(即"HERE1"和"HERE2")上都得到了断言失败。如果我删除static_断言并取消注释打印,我得到了我所期望的:这就是"这里"。对is_pair_type
我猜这意味着编译器不能在编译时计算表达式,但我不明白为什么。
使用:MS VS2019,与MSVC版本14.29.30037
谢谢。
template< class T > struct is_pair : std::false_type {};
template< class T1, class T2 > struct is_pair< std::pair< T1, T2 > > : std::true_type {};
template< class T > struct is_pair_d : is_pair<typename std::decay<T>::type> {};
// a helper function for value
template<class T> struct is_pair_type {
static constexpr bool const value = is_pair_d<T>::value;
};
int main()
{
using T = std::map<int, float>;
T blabla;
if constexpr (is_pair_type<T>::value)
{
//std::cout << "HERE1" << "n";
static_assert(false, "HERE1");
}
else
{
//std::cout << "HERE2" << "n";
static_assert(false, "HERE2");
}
...
Constexpr if应该使用template:
在模板外部,完全检查丢弃的语句。
if constexpr
不能代替#if预处理指令:void f() { if constexpr(false) { int i = 0; int *p = i; // Error even though in discarded statement } }
和
注意:被丢弃的语句不可能对所有可能的专门化都是病态的:
template <typename T> void f() { if constexpr (std::is_arithmetic_v<T>) // ... else static_assert(false, "Must be arithmetic"); // ill-formed: invalid for every T }
您可以将代码包装到函数模板中,如:
template<class T> struct dependent_false : std::false_type {};
template <typename T>
void foo() {
if constexpr (is_pair_type<T>::value)
{
std::cout << "HERE1" << "n";
static_assert(dependent_false<T>::value, "HERE1");
}
else
{
std::cout << "HERE2" << "n";
static_assert(dependent_false<T>::value, "HERE2");
}
}
然后
using T = std::map<int, float>;
foo<T>(); // static_assert fails only on the else part
生活