模板相关的假 [英] Template dependent false
问题描述
我有一个不能直接使用的类模板,只允许专业化.而且我想使用static_assert
来显示有意义的错误消息.
我不能只键入static_assert(false, "error");
,因为false
与值无关,即使从不使用模板,编译器也可能会显示错误消息.
I have a class template which can't be used directly, only specializations are allowed. And I want to use static_assert
to show meaningful error message.
I can't just type static_assert(false, "error");
since false
isn't value dependent and compiler may show error message even if the template is never used.
我的解决方案:
template<class>
struct AlwaysFalse : std::false_type{};
#define DEPENDENT_FALSE(arg) AlwaysFalse<decltype(sizeof(arg))>::value
template<class T>
struct Foo{
static_assert(DEPENDENT_FALSE(T), "You must use specialization!");
};
template<int i>
struct Bar{
static_assert(DEPENDENT_FALSE(i), "You must use specialization!");
};
但是我不确定实现DEPENDENT_FALSE
.因为MSVC 不会将sizeof(arg)
视为模板相关的表达式(很好.
But I'm not sure about realization DEPENDENT_FALSE
. Because MSVC doesn't treat sizeof(arg)
as template dependent expression(unlike GCC), but decltype(sizeof(arg))
is fine.
有人可以用标准来解释这种行为吗?便携吗?
Can somebody explain this behavior in terms of standard? Is it portable?
推荐答案
此:
#define DEPENDENT_FALSE(arg) AlwaysFalse<decltype(sizeof(arg))>::value
实际与无关. decltype(sizeof(arg))
始终是size_t
,它实际上不以任何方式依赖arg
(更广泛地说,这是
fails to actually be dependent. decltype(sizeof(arg))
is always size_t
, it doesn't actually depend on arg
in any way (more broadly, here is a list of expressions that are never type-dependent). Since it's not dependent, a compiler is perfectly able to see that DEPENDENT_FALSE(T)
is false
and just trigger that static_assert
.
您想要的只是:
#define DEPENDENT_FALSE(arg) AlwaysFalse<decltype(arg)>::value
也就是说,放下sizeof
.现在,这是依赖.
That is, drop the sizeof
. This now is dependent.
这将直接对int
不起作用,因为这又不再是依赖项(decltype(i)
只是int
,我们现在需要依赖于值的东西).为此,您可以将其包装在一个整数常量中:
This won't work for the int
directly, since that again won't be dependent (decltype(i)
is just int
, and we need something value-dependent now). For that, you can just wrap it in an integral constant:
template<class T>
struct Foo{
static_assert(AlwaysFalse<T>::value, "You must use specialization!");
};
template<int i>
struct Bar{
static_assert(AlwaysFalse<std::integral_constant<int, i>>::value, "You must use specialization!");
};
这篇关于模板相关的假的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!