gpt4 book ai didi

c++ - 为什么 const 数组优先绑定(bind) const T& 参数而不是 T&& 参数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:08:10 24 4
gpt4 key购买 nike

重载带有“T&&”参数的函数模板通常不是一个好主意,因为它可以绑定(bind)到任何东西,但让我们假设我们仍然这样做:

template<typename T>
void func(const T& param)
{
std::cout << "const T&\n";
}

template<typename T>
void func(T&& param)
{
std::cout << "T&&\n";
}

我的理解是,const T& 重载将针对 const 左值参数调用,而 T&& 重载将针对所有其他参数类型调用。但是考虑一下当我们用 const 和非常量内容的数组调用 func 时会发生什么:

int main()
{
int array[5] = {};
const int constArray[5] = {};

func(array); // calls T&& overload
func(constArray); // calls const T& overload
}

VC10、VC11 和 gcc 4.7 同意显示的结果。我的问题是为什么第二次调用调用 const T& 重载。简单的答案是 constArray 中有一个 const,但我认为这太简单了。推导的类型 T(无论选择的模板如何)是“5 个常量整数的数组”,因此 const T& 重载中的 param 类型将是“对5 个常量整数的常量数组”。但是名为 constArray 的数组本身并未声明为 const。那么,为什么对 func(constArray) 的调用不调用 T&& 重载,从而为 param 生成“对数组的引用”的类型5 个常量整数”?

这个问题的动机是与 c++ template function argument deduce and function resolution 上的问题相关的讨论。 ,但我认为该线程在其他问题上偏离了方向,并没有阐明我现在在这里提出的问题。

最佳答案

在函数参数列表(以及其他任何地方)中,数组类型上的 cv 限定被正确地打乱以限定数组元素类型。例如,对于 T = int [5]const T & 被转换为 int const (&) [5]

3.9.3 CV-qualifiers [basic.type.qualifier]

2 - [...] Any cv-qualifiers applied to an array type affect the array element type, not the array type (8.3.4).

所以调用 func 的参数类型为 int const [5] 被推断为对以下任一调用:

void func<int [5]>(int const (&) [5])
void func<int const (&) [5]>(int const (& &&) [5])
// where the above collapses to
// 'void func<int const (&) [5]>(int const (&) [5])'

两种重载都是可行的,但前者是首选:

令 T1 为 const T & 模板,T2 为 T && 模板;即它们的参数类型为T1 := const T & 和T2 := T &&。然后转换后的参数类型 (14.5.6.2:3) 可以写成 A1 := const C &,A2 := D && 对于合成类型 CD

现在,我们尝试根据 T2 (14.8.2.4:2) 对 T1 进行排序,首先使用 A1 作为参数模板,使用 P2 作为参数模板。我们删除引用 (14.8.2.4:5) 给出 A1 -> const C 和 T2 -> T,然后删除 cv-qualification (14.8.2.4:7) 给出 A1 -> C 和 T2 -> T。模板 T 可以推导为 C (14.8.2.4:8) 所以 A1 至少和 P2 一样专业;相反,A2 -> D -> D,P1 -> const T -> T,和 T 可以推导为 D,因此 A2 至少与 P1 一样专业

这通常意味着两者都不比另一个更专业;然而,因为 PA 类型是引用类型 14.8.2.4:9 适用,并且因为 A1 是左值引用而 P2 不是,T1 被认为比T2。 (引用类型之间的联系也可以通过同一子句下的 cv 限定来打破。)

关于c++ - 为什么 const 数组优先绑定(bind) const T& 参数而不是 T&& 参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12374746/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com