gpt4 book ai didi

c++ - 通用引用和 std::initializer_list

转载 作者:IT老高 更新时间:2023-10-28 22:38:54 25 4
gpt4 key购买 nike

在他的“C++ 和超越 2012:通用引用”演示文稿中,Scott 反复强调了这一点,通用引用 处理/绑定(bind)到所有内容,因此重载已经采用通用引用参数的函数确实没有意义。我没有理由怀疑这一点,直到我将它们与 std::initializer_list 混合在一起。

这是一个简短的例子:

#include <iostream>
#include <initializer_list>
using namespace std;

template <typename T>
void foo(T&&) { cout << "universal reference" << endl; }

template <typename T>
void foo(initializer_list<T>) { cout << "initializer list" << endl; }

template <typename T>
void goo(T&&) { cout << "universal reference" << endl; }

template <typename T>
void goo(initializer_list<T> const&) { cout << "initializer list" << endl; }

int main(){
auto il = {4,5,6};
foo( {1,2,3} );
foo( il );
goo( {1,2,3} );
goo( il );
return 0;
}

奇怪的是,VC11 Nov 2012 CTP 提示歧义(error C2668: 'foo' : ambiguous call to overloaded function)。更令人惊讶的是,gcc-4.7.2、gcc-4.9.0 和 clang-3.4 同意以下输出:

initializer list
initializer list
initializer list
universal reference

因此,显然可以(使用 gcc 和 clang)重载使用 initializer_lists 进行通用引用的函数,但是当使用 auto + { expr } => initializer_list-习惯用法甚至是按值或按 const& 获取 initializer_list 都没有关系。至少对我来说,这种行为完全令人惊讶。哪种行为符合标准?有人知道这背后的逻辑吗?

最佳答案

关键在于:从花括号初始化列表 ({expr...}) 推断类型不适用于模板参数,仅适用于 auto。使用模板参数,你会得到一个推论失败,并且不考虑重载。这导致了第一个和第三个输出。

it does even matter whether one takes the initializer_list by value or by const&

foo:对于任何 X,采用 XX& 参数的两个重载对于左值参数是不明确的- 两者都同样可行(对于 XX&& 对于右值相同)。

struct X{};
void f(X);
void f(X&);
X x;
f(x); // error: ambiguous overloads

但是,部分排序规则在这里介入(第 14.5.6.2 节),采用通用 std::initializer_list 的函数比采用通用的函数更专业任何东西。

goo:对于两个带有 X&X const& 参数和一个 X& 参数的重载,第一个更可行,因为第二个重载需要从 X&X const&限定转换(第 13.3.3.1 节。 2/1 表 12 和 §13.3.3.2/3 第三个子项目符号)。

关于c++ - 通用引用和 std::initializer_list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17314691/

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