c++ structed bindings & std::optional & std::variant&std::any

2023-03-23

ps: 这是c++17的新特性

structed bindings

structed bingdings是c++17的新特性

#include <iostream>
#include <string>
#include <tuple>

std::tuple<std::string,int> CreatePerson() {
	return { "wsxk",22 };
}

int main() {
	std::tuple<std::string, int> person = CreatePerson();
	std::string name = std::get<0>(person);
	std::cout << name << std::endl;
	int age = std::get<1>(person);
	std::cout << age << std::endl;

	std::tie(name, age) = CreatePerson();
	
	auto [name2, age2] = CreatePerson(); //structed bindings
}

optional

optional同样是c++17的新特性

#include <iostream>
#include<optional>
#include <fstream>
#include <string>

std::optional<std::string> ReadFileAsString(const std::string &filepath) {
	std::ifstream stream(filepath);
	if (stream) {
		std::string result;
		// read file
		stream.close();
		return result;
	}
	return {};
}

int main() {
	std::optional<std::string> data = ReadFileAsString("data.txt");
	std::string value = data.value_or("wsxk");
	std::cout << value << std::endl;
	if (data.has_value()) {
		std::cout << "read successfully\n";
	}
	else {
		std::cout << "read failed\n";
	}

}

std::variant

std::variant是c++17的新特性,允许我们不用考虑变量问题

#include <iostream>
#include <variant>
#include <string>

int main() {
	std::variant<std::string, int> data;
	data = "wsxk";
	std::cout << std::get<std::string>(data) << std::endl;
	data = 2;
	std::cout << std::get<int>(data) << std::endl;

	// std::variant<std::string, int> data;
	// data = "wsxk";
	// std::cout << data.index() << std::endl;
	// auto value = std::get_if<std::string>(&data);
	// std::cout << *value << std::endl;
	// data = 2;
	// auto value2 = std::get_if<int>(&data); //是否是int类型,是,返回指针;否,返回0
	// std::cout << *value2 << std::endl;
	// std::cout << data.index() << std::endl;
	
}

值得注意的是 std::variant和union有较大不同,std::variant保留了每个可能变量的空间。而union只取最大的

#include <iostream>
#include <variant>
#include <string>
int main() {
	std::variant<std::string, int> data;
	std::cout << sizeof(int) << std::endl;
	std::cout << sizeof(std::string) << std::endl;
	std::cout << sizeof(std::variant<std::string,int>) << std::endl;
}

std::any

std::any是c++17新特性,和std::variant很像

#include <any>
#include <iostream>
int main() {
	std::any data;
	data = "wsxk";
	std::cout << std::any_cast<const char *>(data) << std::endl;//如果实际data中并不是你想要的数据,会抛出异常
}

std::any在申请类型比较小的例子时和std::variant一样,申请大类型时,会涉及到动态内存分配,影响程序性能,而且std::variant是std::any的安全版本,所以,尽量别用。