logo生成,网站关键词优化多少钱,wordpress 留言汉化,网站后台管理系统登录C17中的结构化绑定(structured binding):将指定名称绑定到初始化程序的子对象或元素。简而言之#xff0c;它们使我们能够从元组或结构中声明多个变量。与引用一样#xff0c;结构化绑定是现有对象的别名#xff1b;与引用不同#xff0c;结构化绑定不必是引用类型(referen… C17中的结构化绑定(structured binding):将指定名称绑定到初始化程序的子对象或元素。简而言之它们使我们能够从元组或结构中声明多个变量。与引用一样结构化绑定是现有对象的别名与引用不同结构化绑定不必是引用类型(reference type)。 C17中结构化绑定的主要目的是使代码干净且易于理解。结构化绑定允许你在单个声明中将多个变量绑定到结构化对象的元素例如std::tuple或struct。 每个结构化绑定都有一个引用类型,该类型是decltype在应用于无括号的结构化绑定时返回的类型:E表示初始化表达式的类型 (1).binding an array:标识符的数量必须等于数组元素的数量;每个标识符的引用类型是数组元素类型; 注意如果数组类型是cv限定的那么它的元素类型也是cv限定的
int arr1[3] { 1, 2, 3 };auto [x, y, z] arr1; // 拷贝
std::cout x: x ,y: y ,z: z \n; // x:1,y:2,z:3
x 4;
std::cout arr1: arr1[0] \n; // arr1:1auto [x2, y2, z2] arr1; // 引用
std::cout x2: x2 ,y2: y2 ,z2: z2 \n; // x2:1,y2:2,z2:3
x2 5;
std::cout arr1: arr1[0] \n; // arr1:5const auto [x3, y3, z3] {arr1};
const auto [x4, y4, z4](arr1);
std::cout x3: x3 ,x4: x4 \n; // x3:5,x4:5 (2).binding a tuple-like type:表达式std::tuple_sizeE::value必须是格式正确的整型常量表达式并且标识符的数量必须等于std::tuple_sizeE::value
std::tuplestd::string, int, float foo{ csdn, 8, 6.6 };const auto [x3, y3, z3] foo;
std::cout x3: x3 ,y3: y3 ,z3: z3 \n; // x3:csdn,y3:8,z3:6.6auto [x4, y4, z4] foo;
x4 github;
y4 6;
z4 8.8;
std::cout foo: std::get0(foo) , std::get1(foo) , std::get2(foo) \n; // foo:github,6,8.8int a 1, b 2;
const auto [x6, y6] std::tie(a, b); // x6 and y6 are of type int
x6 6;
auto [x7, y7] std::tie(a, b); // x7 and y7 are still of type int
std::cout x7: x7 ,a: a \n; // x7:6,a:6
x7 8;
std::cout x6: x6 ,a: a \n; // x6:8,a:8
if (x6 ! x7)std::cout Error: x6 ! x7\n; // 不会执行 (3).binding to data members:标识符的数量必须等于非静态数据成员的数量
namespace {typedef struct Info {mutable std::string name;volatile int number;
} Info;inline Info func()
{return Info{ csdn, 666 };
}typedef struct Data {int b{ 1 }, d{ 2 }, p{ 3 }, q{ 4 };
} Data;} // namespaceconst auto [x5, y5] func();
std::cout x5: x5 ,y5: y5 \n; // x5:csdn,y5:666
x5 github;
//y5 888; //表达式必须是可修改的左值,需将const auto[x5, y5]调整为auto[x5, y5]const auto [b1, d1, p1, q1] Data{};
std::cout b1: b1 ,d1: d1 ,p1: p1 ,q1: q1 \n; // b1:1,d1:2,p1:3,q1:4const auto [b2, d2, p2, q2] Data{ 4, 3, 2, 1 };
std::cout b2: b2 ,d2: d2 ,p2: p2 ,q2: q2 \n; // b2:4,d2:3,p2:2,q2:1Data s;
auto [b3, d3, p3, q3] s;
std::cout b3: b3 ,d3: d3 ,p3: p3 ,q3: q3 \n; // b3:1,d3:2,p3:3,q3:4b3 4, d3 3, p3 2, q3 1;
std::cout s.b: s.b ,s.d: s.d ,s.p: s.p ,s.q: s.q \n; // s.b:4,s.d:3,s.p:2,s.q:1 注意 (1).结构化绑定无法受到约束 (2).lambda表达式无法捕获结构化绑定(C20中可以) (3).必须确保在适当的时刻使用引用尽量减少不必要的拷贝 (4).使用结构化绑定时就不能再使用std::tie创建虚拟变量 (5).结构化绑定中有一个隐藏的匿名对象结构化绑定时引入的新变量名其实都指向这个匿名对象的成员/元素 (6).可以在结构化绑定中使用修饰符如const和引用这些修饰符会作用在新的匿名实体上而不是结构化绑定引入的新的变量名上 (7).理论上讲结构化绑定适用于任何有public数据成员的结构体、C风格数组和类似元组(tuple-like)的对象; (8).在任何情况下结构化绑定中声明的变量名的数量都必须和元素或数据成员的数量相同; (9).使用结构化绑定需要继承时需要遵循一定的规则所有的非静态数据成员必须在同一个类中定义(也就是说这些成员要么是全部直接来自于最终的类要么是全部来自同一个父类)并且只有当public成员的顺序保证是固定的时候你才应该使用结构化绑定 (10).结构化绑定机制是可拓展的你可以为任何类型添加对结构化绑定的支持。标准库中就为std::pair、std::tuple、std::array添加了支持
const std::mapstd::string, std::string addrs{{csdn, https://blog.csdn.net/fengbingchun/},{github, https://github.com/fengbingchun}
};for (const auto [key, val] : addrs) {std::cout key: key , addr: val \n; // key: csdn, addr: https://blog.csdn.net/fengbingchun/// key: github, addr: https://github.com/fengbingchun
}Info info{ github, 888 };
auto [u, v] std::move(info); // u和v指向的匿名实体是info的右值引用,同时info仍持有值
std::cout info.name: info.name \n; // info.name:github
Info info2{ csdn, 666 };
auto [u2, v2] std::move(info2); // info2已失去了值
std::cout info2.name: info2.name \n; // info2.name: 执行结果如下图所示 GitHubhttps://github.com/fengbingchun/Messy_Test