为什么通用引用不适用于数组?

Why doesn't universal reference apply for arrays?

#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
}

我的编译器是 clang 7.0 -std=c++17

为什么通用引用不适用于数组?

首先这些官方叫"forwarding references",不是"universal references".

你的 static_assert 失败是因为在将左值传递给采用 "forwarding reference"[ 的函数时,T 被推断为 T& =33=] - 这是 "forwarding references" 的特殊规则之一,适用于模板参数推导。

您可以通过先删除任何引用来修复您的断言:

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

live example on godbolt.org


std::remove_cvref_t 是 C++20 的前沿特性——如果您的编译器不支持,您可能想使用 std::remove_reference_t

template argument deduction发生时这里的相关规则是:

Deduction from a function call
...
4. If P is an rvalue reference to a cv-unqualified template parameter (so-called forwarding reference), and the corresponding function call argument is an lvalue, the type lvalue reference to A is used in place of A for deduction.

因此,在您的情况下,arr 被推断为 arr 的引用,因此 static_assert 失败。