Прежде всего, они официально называются "отправляющими ссылками" , а не "универсальными ссылками" .
Ваш static_assert
терпит неудачу из-за того, что T
выводится как T&
при передаче lvalue в функцию, принимающую "ссылку на пересылку" - это одно из специальных правил "пересылка ссылок" , которые применяются во время вывода аргумента шаблона.
Вы можете исправить свое утверждение, удалив сначала любую ссылку:
static_assert(std::is_array_v<std::remove_cvref_t<T>>);
живой пример на godbolt.org
std::remove_cvref_t
- это новейшая функция C ++ 20 - вы можете использовать std::remove_reference_t
вместо этого, если ваш компилятор ее не поддерживает.