Эквивалентные static_asserts, дающие противоречивые результаты для is_array & lt; & gt;

В следующем фрагменте статическое утверждение проходит, а другое не выполняется:

template <class Rng> constexpr bool is_array(Rng&& r) {
// int*** debug = r;  // uncomment this to debug r's type
return std::is_array<Rng>{};
// return std::is_array<decltype(r)>{};  // fails too
}

int a[5] = {0, 1, 2, 3, 4};
static_assert(std::is_array<decltype(a)>{}, ""); // passes
static_assert(is_array(a), ""); // fails

Подсказка: удалите комментарий для отладки типа (он правильно выводится как int [5]).

Почему это? Проверено на лязг ствола.

Я предполагаю, что это как-то связано с массивами, распадающимися на указатели … как-то.

Решение: использовать std::remove_reference_t, Rng будет int (&)[5], это ссылка на массив, а не массив.

Xeo добавил:

template<class> struct dump;
dump<decltype(r)>{};

не сможет скомпилировать и раскрыть правильный тип r,

int**** j = r; выдал неправильную ошибку int[5] в int****).

3

Решение

Тип Rng является int (&)[5] которая является ссылкой на массив (а не массив) и, следовательно, std::is_array возвращается false_type,

Можно удалить ссылку (например, используя std::remove_reference_t) чтобы все работало так, как вы ожидали.

0

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


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