Определение специализации std :: numeric :: type & lt; T & gt; для некоторого нечислового типа T

Я хочу проверить, есть ли у типа запись в std :: numeric_limits. Когда тип является массивом (или, возможно, не числом?), Я получаю ошибку компилятора. Это мешает мне обнаруживать и переходить в зависимости от того, поддерживается ли тип в std :: numeric_limits. Буду признателен за любую информацию, которой хочет поделиться.

// the following provokes compiler error on Clang
// Function cannot return array type 'type' (aka 'char [20]')
static_assert(
! std::numeric_limits<char[20]>::is_specialized,
"! std::numeric_limits<char[20]>::is_specialized");
// invokes static assert on compile as expected
static_assert(
std::numeric_limits<char[20]>::is_specialized,
"std::numeric_limits<char[20]>::is_specialized");

7

Решение

Это происходит потому, что если вы посмотрите внутрь std::numeric_limits или посмотрите на документацию, вы увидите объявления о методах, подобных следующему

template<class T>
class numeric_limits
{
public:
static constexpr bool is_specialized = false;
static constexpr T min() noexcept;
static constexpr T max() noexcept;
static constexpr T lowest() noexcept;

Здесь, как вы можете видеть, есть функции, которые возвращают T по значению, а C ++ не поддерживает возврат типов массивов по значению (см. Почему C ++ не поддерживает функции, возвращающие массивы?)

Так что следующая строка не скомпилируется

std::numeric_limits<char[20]>::is_specialized

И любая дальнейшая попытка напрямую проверить, is_specialized работает для типа непосредственно с SFINAE не будет компилироваться, потому что возникнет ошибка (из-за возврата типов массива, как объяснено выше), которая не находится в непосредственном контексте шаблона. Таким образом, вам нужно будет проверить концепцию, которая поддерживается для std::numeric_limits (в этом случае std::is_arithmetic)

Однако все, что вам нужно сделать здесь, чтобы сделать эту работу, это std::decay_t тип

std::numeric_limits<std::decay_t<char[20]>>::is_specialized

И теперь это будет работать, потому что вы явно распалили тип массива на указатель, который можно вернуть из функции. Вы, вероятно, хотели сделать это в первую очередь, потому что вы не хотите случайно позвонить std::numeric_limits::is_specialized для не гниющего типа, как const int&

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]