莫名的覺得這三個類好像,所以就放在一塊學(xué)習(xí)一下,感覺就是一個代表很多類型的類。
-
std::any
一個類型安全的容器,可以放置各種類型的數(shù)據(jù)。
#include <any>
#include <iostream>
int main()
{
std::cout << std::boolalpha; //將bool值用 "true" 和 "false"顯示
std::any a; //定義一個空的any,即一個空的容器
//有兩種方法來判斷一個any是否是空的
std << cout << a.has_value() <<std::endl; // any是空的時,has_value 返回值為 false
std << cout << a.type().name() <<std::endl; //any 是空的時,has_value 返回值為 true
//幾種創(chuàng)建any的方式
std::any b = 1; //b 為存了int類型的值的any
auto c = std::make_any<float>(5.0f); //c為存了float類型的any
std::any d(6.0); //d為存儲了double類型的any
std << cout << b.has_value() <<std::endl; //true
std << cout << b.type().name() <<std::endl; //int
std << cout << c.has_value() <<std::endl; //true
std << cout << c.type().name() <<std::endl; //float
std << cout << d.has_value() <<std::endl; //true
std << cout << d.type().name() <<std::endl; //double
//更改any的值
a = 2; //直接重新賦值
auto e = c.emplace<float>(4.0f); //調(diào)用emplace函數(shù),e為新生成的對象引用
//清空any的值
b.reset();
std << cout << b.has_value() <<std::endl; //false
std << cout << b.type().name() <<std::endl; //int
//使用any的值
try
{
auto f = std::any_cast<int>(a); //f為int類型,其值為2
std::cout << f <<std::endl; //2
}
catch(const std::bad_any_cast& e)
{
std::cout<< e.what()<<std::endl;
}
try
{
auto g = std::any_cast<float>(a); //拋出std::bad_any_cat 異常
std::cout << g <<std::endl; //該語句不會執(zhí)行
}
catch(const std::bad_any_cast& e)
{
std::cout<< e.what()<<std::endl; //可能輸出Bad any_cast
}
return 0;
-
std::variant
std::variant是類型安全的union
#include <variant>
#include <iostream>
union my_union
{
int i;
float f;
char c;
};
int main()
{
std::cout << std::boolalpha;
std::variant<int, float, char> variant;
//這里的variant等價于my_union
//在構(gòu)造的時候,如果構(gòu)造過程中拋出了異常,valueless_by_exception的返回值為true
std::cout<< variant.valueless_by_exception()<<std::endl; //false
{
variant = 12; // variant包含了int類型
int i = std::get<int>(variant); //使用std::get<T>可以獲取所含有的值
try
{
auto f = std::get<float>(variant); //此時的值為int,所以想要獲取float的時候就會拋出異常
}
catch (const std::bad_variant_access & exception)
{
std::cout << exception.what() << std::endl;
}
variant = 1.0f;
auto f = std::get<float>(variant);
std::cout << f << std::endl; //1.0
}
{
//還可以使用索引來獲取對應(yīng)的值
auto f = std::get<1>(variant);
try
{
auto i = std::get<0>(variant);
}
catch (const std::bad_variant_access & exception)
{
std::cout << exception.what() << std::endl;
}
variant = 1;
auto i = std::get<0>(variant);
std::cout<<i<<std::endl; //1
}
variant = 2.0f;
std::cout << variant.index() << std::endl; //1
variant = 2;
std::cout << variant.index() << std::endl; //0
return 0;
}
-
std::optional
該類型是用來表示一個值是不是存在的。std::optional有兩個狀態(tài),即有值和無值。通常我們將std::optional用于函數(shù)的返回值,當(dāng)函數(shù)執(zhí)行成功了返回有值的狀態(tài),當(dāng)函數(shù)執(zhí)行失敗了返回?zé)o值的狀態(tài)。當(dāng)std::optional有值時,它可以在使用bool值的地方轉(zhuǎn)化為true,反之,轉(zhuǎn)化為false。
#include <iostream>
#include <optional>
int main()
{
std::cout << std::boolalpha;
std::optional<int> op1; //表示一個不存在的值
std::optional<int> op2 = 1; //表示一個存在的int類型的值
std::optional<int> op3(2); //表示存在的一個int類型的值
std::optional<std::string> op4(std::in_place, 3, 'A'); //構(gòu)建一個存有std::string類型的std::optional,
//調(diào)用std::string的構(gòu)造函數(shù),其值為"AAA"
std::cout << op1.has_value() << std::endl; //輸出為false
if (!op1)
{
std::cout << "empty optional is false" << std::endl; //由于op1不存在值,所以在此轉(zhuǎn)化為false
}
try
{
std::cout << op4.value() << std::endl; //獲取std::optional 的值,如果不存在值,則拋出std::bad_optional_access異常
}
catch (std::bad_optional_access & e)
{
std::cout << e.what() << std::endl;
}
std::optional<int> op5;
std::cout<<op5.value_or(5)<<std::endl;
op2.reset();
std::cout << op2.has_value() << std::endl; //false
op2 = 3;
op2 = 4.0;
std::cout << op2.value() << std::endl; //4.0
op2.emplace<int>(5);
return 0;
}