第三节 · 摆脱单亲状态 · 多重继承与虚继承
有时我们需要存储任意类型的值,C++17 提供了 std::any 来实现类型安全的类型擦除。
void 的问题*
// 旧方法:不安全
void* data = new int(42);
int* p = static_cast<int*>(data); // 必须记住类型
cout << *p << endl;
delete static_cast<int*>(data);
// 如果类型记错了,就是未定义行为
string* s = static_cast<string*>(data); // 危险!std::any
#include <any>
int main()
{
any a = 42;
cout << any_cast<int>(a) << endl; // 42
a = string("Hello");
cout << any_cast<string>(a) << endl; // Hello
a = 3.14;
cout << any_cast<double>(a) << endl; // 3.14
// 类型不匹配会抛出异常
try
{
cout << any_cast<int>(a) << endl;
}
catch (const bad_any_cast& e)
{
cout << "Bad cast: " << e.what() << endl;
}
return 0;
}any 的操作
std::variant
variant 是类型安全的联合体。
访问者模式与 variant
std::optional
表示可能没有值的类型。
手动实现类型擦除
函数包装器 std::function
类型擦除的应用
习题
比较
any、variant和void*的优缺点。实现一个简单的属性系统,支持任意类型的属性值。
使用
variant实现一个简单的 JSON 值类型。
Last updated