我正在寻找一种在编译时将类型映射到数值的方法,理想情况下不使用this答案中建议的哈希。
由于指针可以是constexpr
,所以我尝试了此操作:
struct Base{};
template<typename T> struct instance : public Base{};
template<typename T>
constexpr auto type_instance = instance<T>{};
template<typename T>
constexpr const Base* type_pointer = &type_instance<T>;
constexpr auto x = type_pointer<int> - type_pointer<float>; // not a constant expression
gcc和clang都拒绝此代码,因为type_pointer<int> - type_pointer<float>
不是常数表达式,例如,请参见here。
为什么?
我可以理解,两个值之间的差异从一个编译到下一个编译将不会稳定,但是在一个编译中,应该是constexpr
,恕我直言。
两个未指向同一数组或同一对象(包括一个过去的对象)的非空指针的减法是未定义的行为。
如果被评估,将具有核心未定义行为的表达式是never常量表达式,请参见C ++ 17标准的[expr.const]/2.6(最终草案)。
因此type_pointer<int> - type_pointer<float>
不能为常量表达式,因为两个指针都指向不相关的对象。
由于type_pointer<int> - type_pointer<float>
不是常数表达式,因此不能用于初始化constexpr
变量,例如
constexpr auto x = type_pointer<int> - type_pointer<float>;
,导致错误消息。
如果指针指向同一个对象,您将看到没有错误,例如:
constexpr auto x = type_pointer<int> - type_pointer<int>;
这里,减法是定义明确的,并且初始化程序是一个常量表达式。因此,代码将进行编译(并且不会具有未定义的行为)。 x
将具有明确定义的0
值。