C++20结构化绑定作为返回值的构造函数选择及编译器差异问题
C++20结构化绑定返回值构造函数匹配问题解答
结论
按照C20标准,应当选择A(const int &)构造函数,Clang的实现符合标准,GCC当前行为不符合C20规范。
规则拆解
1. 结构化绑定的底层逻辑
代码中auto [y] = std::make_tuple(1);的执行逻辑符合C++结构化绑定规则,等价于如下步骤:
- 首先创建一个隐藏的匿名tuple左值对象:
auto __hidden_tuple = std::make_tuple(1);,类型为std::tuple<int> - 绑定名
y是std::get<0>(__hidden_tuple)的别名,对于左值tuple,std::get<0>返回int&类型的左值引用,因此y是int类型的左值。
2. return语句的隐式移动规则
C++20中return语句触发隐式移动的前提是:return的操作数是函数作用域内的局部对象变量或者非引用类型的函数形参。
结构化绑定引入的y只是元素别名,不属于独立的局部对象变量,因此不满足隐式移动的触发条件,return时y仍然作为左值参与重载决议。
3. 重载决议匹配
左值int无法绑定到右值引用int&&,只能匹配const int&形参,因此最终调用A(const int &)构造函数。
复现代码
#include <tuple> #include <iostream> struct A { A(const int &) { std::cout << "A(const int &) "; } A(int &&) { std::cout << "A(int &&) "; } }; A foo() { auto [y] = std::make_tuple(1); return y; } int main() { foo(); }
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

