Я хочу проверить, есть ли у типа запись в 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");
Это происходит потому, что если вы посмотрите внутрь 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&
Других решений пока нет …