结构化绑定
处理多个返回值的操作:C++17提出
之前多返回值喜欢用struct来返回。现在会做成元组,下图中设置C++17的版本,不要设置错为C语言标准。
#include<iostream>
#include<string>
#include<tuple>
std::pair<std::string, int> CreatPerson() {
return { "lhx",25 };
}
std::tuple<std::string, int> CreatPerson2() {
return { "lhx",25 };
}
std::tuple<std::string, int, int, int> CreatPerson1() {
return { "lhx",25,1,1 };
}
int main() {
auto person = CreatPerson1();
std::string& name = std::get<0>(person);
int& name = std::get<1>(person);
std::string name;
int age;
int age1;
int age2;
std::tie(name, age,age1,age2) = CreatPerson1();
//结构化绑定
auto [name, age] = CreatPerson2();
}
在C++17结构化绑定之前我们使用tuple或者struct来接收数据,现在可以直接使用结构化绑定来解决。
optional
不能只使用data.value_or来判断文件是否存在,因为文件存在没有内容照样会输出
std::optional<std::string> ReadFileAsString(const std::string& filepath){
std::ifstream stream(filepath);
if (stream) {
std::string result;
stream.close();
return result;
}
return {};
}
int main() {
std::optional<std::string> data = ReadFileAsString("data1.txt");
auto value = data.value_or("Not present");
std::cout << value << std::endl;
if (data.has_value()) {
std::cout << "file read success";
}
else {
std::cout << "file not opend";
}
std::cin.get();
}
所以直接选择optional类型,其可以用于表示值存不存在的问题,在处理这种打开是否有效的这种情况非常好用。
variant类型
variant可以声明变量可以是几种不同的类型值,与联合体不同的是,这几个值分别占各自的空间。
.index方法可以返回索引值,读取使用std::get<类型>()读取。
std::variant<std::string, int> temp;
temp = 111;
temp.index();
if (auto* ptr = std::get_if<std::string>(&temp)) {
std::cout << "string!!" << "\n";
}
else {
std::cout << "int!!!!" << "\n";
}
std::cout << std::get<std::string>(temp) << "\n";
问题:union和这个variant有什么不同?
union只能存储基本类型,不能存储std::string,并且内存只取最大的,而variant是定义之和。
问题:使用std::variant为什么定义了两种类型,一直只能使用一种类型,但是空间却还是两种类型的空间,为什么不能像联合体那样声明空间最大的类型的空间,而不是两者之和的空间。
std::variant
的设计考虑了类型安全性和易用性,这是以牺牲一些额外的内存开销为代价的。虽然这看起来可能不如联合体那样高效,但std::variant
提供的特性和安全性在很多情况下是非常有价值的。
union mutiType
{
float test1;
int test2;
};
int main() {
std::variant<float, int> temp;
mutiType test3;
test3.test1 = 2.0f;
test3.test2 = 1;
std::cout << sizeof(int) << "\n";
std::cout << sizeof(float) << "\n";
std::cout << sizeof(test3) << "\n";
std::cout << sizeof(temp) << std::endl;
}
还可以使用std::variant来代替optional进行值返回。
std::variant<std::string,int> ReadFileAsString(const std::string& filepath){
std::ifstream stream(filepath);
if (stream) {
std::string result;
stream.close();
return result;
}
return 123;
}