Hol*_*Cat 39 c++ std compile-time language-lawyer
考虑这个代码:
#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>);
}
Run Code Online (Sandbox Code Playgroud)
如果我使用<
而不是std::less
这里,代码不会编译。这并不奇怪,因为如果指针指向不相关的对象,则关系指针比较的结果是未指定的,而且显然这样的比较不能在编译时完成。
Run Code Online (Sandbox Code Playgroud)#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
. 编译器错误是一样的。std::less
似乎<
至少在 libstdc++ 和 libc++ 中实现;我在 GCC、Clang 和 MSVC 上得到了相同的结果。
但是,关于 cppreference 的页面std::less
声称:
它operator()
是constexpr
。
它神奇地在指针上实现了严格的全序,即可用于将不相关的指针与合理的结果进行比较。
那么,它是所有这些编译器中的一个错误,还是我遗漏了一些关于std::less
使上面的代码格式错误的细节?
Bri*_*ian 28
我认为您提出的问题没有明确的答案。这是LWG 2833 的一个特例:标记库函数constexpr
并不能解释在何种情况下调用该函数会产生一个常量表达式。
在这个问题得到解决之前,我认为你不能依赖于std::less
能够在编译时比较不相关的指针。
要成为有效的constexpr
函数,它应该具有结果为 的参数,而constexpr
不是所有参数。
例如
constexpr int foo(bool b) { if (!b) throw 42; return 42; }
Run Code Online (Sandbox Code Playgroud)
有效,f(true)
可以在 constexpr 中使用(即使f(false)
不能)。
constexpr int a[2]{};
constexpr bool b = std::less<const void*>{}(&a[0], &a[1]);
Run Code Online (Sandbox Code Playgroud)
是有效的,就足以让less::operator()
成constexpr
。
我认为没有指定标准中的 constexpr 哪些范围/值是正确的。
所以所有的编译器都是正确的。
归档时间: |
|
查看次数: |
1095 次 |
最近记录: |