Why doesn't universal reference apply for arrays?

  • A+
Category:Languages
#include <type_traits>  template<typename T> void f(const T&) {     static_assert(std::is_array_v<T>); // ok }  template<typename T> void g(T&&) {     static_assert(std::is_array_v<T>); // error }  int main() {     char arr[8];     f(arr); // ok     g(arr); // error } 

My compiler is clang 7.0 with -std=c++17.

Why doesn't universal reference apply for arrays?

 


First of all, these are officially called "forwarding references", not "universal references".

Your static_assert fails due to the fact that T is deduced as T& when passing an lvalue to a function taking a "forwarding reference" - this is one of the special rules of "forwarding references" that apply during template argument deduction.

You can fix your assert by stripping any reference out first:

static_assert(std::is_array_v<std::remove_cvref_t<T>>);  

live example on godbolt.org


std::remove_cvref_t is a bleeding edge C++20 feature - you might want to use std::remove_reference_t instead if your compiler doesn't support it.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: