Рассмотрим этот код:
#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>);
}
Запуск на g cc .gotbolt.org
Если я использую <
вместо std::less
здесь код не компилируется. Это неудивительно, потому что результат сравнения реляционных указателей не указан , если указатели указывают на несвязанные объекты, и, очевидно, такое сравнение не может быть выполнено во время компиляции.
<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 ++; Я получаю те же результаты на G CC, Clang и MSV C.
Однако на странице cppreference about std::less
утверждается, что:
Его operator()
равно constexpr
.
Он волшебным образом реализует строгий общий порядок указателей, т.е. может использоваться для сравнения несвязанных указателей с разумными результатами.
Итак, это ошибка всех этих компиляторов, или мне не хватает каких-то деталей о std::less
, из-за которых приведенный выше код имеет неправильный формат?