【发布时间】:2020-10-10 23:48:30
【问题描述】:
考虑这段代码:
#include <functional>
#include <typeinfo>
template <typename T>
inline constexpr const void *foo = &typeid(T);
int main()
{
constexpr bool a = std::less<const void*>{}(foo<int>, foo<float>);
}
如果我在这里使用< 而不是std::less,则代码无法编译。这并不奇怪,因为如果指针指向不相关的对象,则关系指针比较的结果是 unspecified,显然这样的比较不能在编译时完成。
<source>:9:20: error: constexpr variable 'a' must be initialized by a constant expression constexpr bool a = foo<int> < foo<float>; ^ ~~~~~~~~~~~~~~~~~~~~~ <source>:9:33: note: comparison has unspecified value constexpr bool a = foo<int> < foo<float>; ^
即使我使用std::less,代码仍然无法编译。编译器错误是一样的。 std::less 似乎至少在 libstdc++ 和 libc++ 中实现为 <;我在 GCC、Clang 和 MSVC 上得到了相同的结果。
但是,关于 std::less 的 cppreference 页面声称:
-
它的
operator()是constexpr。 -
它神奇地实现了对指针的严格全序,即可用于将不相关的指针与合理的结果进行比较。
那么,这是所有这些编译器中的一个错误,还是我遗漏了一些关于 std::less 的细节导致上面的代码格式错误?
【问题讨论】:
-
离题:在比较之前将两个指针都转换为 uintptr_t 对我来说不会出现 'magical'...
-
@Aconcagua 如果是这样,那它就不可能是
constexpr。 -
如果你不使用
a,它可以简单地优化掉。如果你使用它会发生什么?例如,return a ? 99 : 101 ; -
@TonyK 即使不使用变量,代码也不会编译,所以我怀疑如果我以某种方式使用它会编译。
标签: c++ language-lawyer std compile-time