C++17带来了一个新特性,它结合了语法糖和自动类型推断:结构化绑定。这有助于将对、元组和结构体中的值赋给单独的变量。在其他编程语言中,这也称为解包?
#include <iostream>
#include <chrono>
std::pair<int, std::string> func(int a, int b)
{
if (b <= 0){
return { -1, "error" };
}else{
return { a / b, "ok" };
}
}
std::tuple<int, std::string, std::chrono::system_clock::time_point> func1()
{
return std::make_tuple(0, "ok", std::chrono::system_clock::now());
}
int main()
{
//C++17 之前
const auto result = func(1, 0);
std::cout << "result: " << result.first << "," << result.second << std::endl;
//c++17 之后
auto [code, err] = func(1, 0);
std::cout << "result: " << code << "," << err << std::endl;
auto [code1, err1, nowclock] = func1();
std::cout << "Hello World!\n";
}
我们现在可以将单个值分配给具有表达性名称的单个变量,这样读起来更好。
结构化绑定应用到自定义结构体:
#include <iostream>
#include <chrono>
#include <vector>
struct employee
{
unsigned int id;
std::string name;
std::string role;
unsigned salary;
};
int main()
{
std::vector<employee> vecEly;
employee ely;
ely.id = 0;
ely.name = "张三";
ely.role = "员工";
ely.salary = 5000;
vecEly.emplace_back(ely);
ely.id = 1;
ely.name = "李四";
ely.role = "员工";
ely.salary = 6000;
vecEly.emplace_back(ely);
ely.id = 2;
ely.name = "王五";
ely.role = "员工";
ely.salary = 8000;
vecEly.emplace_back(ely);
for (const auto &[id, name, role, salary] : vecEly)
{
std::cout << "id: " << id << " name: " << name << " role: "
<< role << " salary: " << salary << std::endl;
}
std::cout << "Hello World!\n";
}
STL中的许多基本数据结构都可以使用结构化绑定立即访问,而无需更改任何内容。例如,考虑一个循环,它输出std::map的所有项:
#include <iostream>
#include <chrono>
#include <vector>
#include <map>
struct employee
{
unsigned int id;
std::string name;
std::string role;
unsigned salary;
};
int main()
{
std::map<int, employee> mapEly;
std::vector<employee> vecEly;
employee ely;
ely.id = 0;
ely.name = "张三";
ely.role = "员工";
ely.salary = 5000;
vecEly.emplace_back(ely);
mapEly[0] = ely;
ely.id = 1;
ely.name = "李四";
ely.role = "员工";
ely.salary = 6000;
vecEly.emplace_back(ely);
mapEly[1] = ely;
ely.id = 2;
ely.name = "王五";
ely.role = "员工";
ely.salary = 8000;
vecEly.emplace_back(ely);
mapEly[2] = ely;
for (const auto& [id, name, role, salary] : vecEly)
{
std::cout << "id: " << id << " name: " << name << " role: "
<< role << " salary: " << salary << std::endl;
}
for (const auto& [index, elyData] : mapEly)
{
std::cout << "index: " << index
<< " id: " << elyData.id << " name: " << elyData.name << " role: "
<< elyData.role << " salary: " << elyData.salary << std::endl;
}
std::cout << "Hello World!\n";
}
性能担忧:
除了C语言中缺少的语言特性外,通过返回值返回复杂结构在很长一段时间内被认为是缓慢的,因为对象必须在返回函数中初始化,然后复制到应该包含调用方返回值的变量中。现代编译器支持返回值优化(RVO),它允许省略中间副本。