为什么通用引用不适用于数组?
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>>);
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
失败。
#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>>);
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
失败。