c++ - 如果所有选项都满足一个接口,可以使用 boost 变体进行类型擦除吗?
问题描述
我有一些代码,其中 boost::variant 中的每个元素都实现了一个通用接口。由于各种原因,我不想将它们存储为已擦除类型。有没有一种简单的方法可以在给定变体的情况下访问界面,而无需为每种可能的情况编写访问者?我在下面得到的具体错误都在投射线上,如下:
error C2100: illegal indirection
error C2440: 'static_cast': cannot convert from 'animal *' to 'iAnimal *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
error C2227: left of '->speak' must point to class/struct/union/generic type
#include <iostream>
#include "Boost/variant.hpp"
class iAnimal
{
public:
virtual std::string speak() = 0;
virtual ~iAnimal() {};
};
struct cat : public iAnimal
{
std::string speak()
{
return "Meow!";
}
};
struct dog : public iAnimal
{
std::string speak()
{
return "Woof!";
}
};
int main()
{
typedef boost::variant<cat, dog> animal;
animal fluffy = cat();
std::cout << static_cast<iAnimal*>(&*fluffy)->speak() << std::endl;
return 0;
}
解决方案
你可能会使用类似的东西:
boost::variant<cat, dog> animal;
animal fluffy = cat();
boost::apply_visitor([](auto& e) -> iAnimal& { return e; }, fluffy).speak();
在 C++17 中,使用 std,它将是
std::variant<cat, dog> animal;
animal fluffy = cat();
std::visit([](auto& e) -> iAnimal& { return e; }, fluffy).speak();
推荐阅读
- python - 在 Python 中使用元组索引的值对字典进行排序
- android - 此处地图导航不适用于 Android 的画中画模式
- android - Android 模拟器使用的内存超出了应有的范围
- flutter - 如何与在 Dart/Flutter 中执行阻塞操作的隔离体进行通信?
- reactjs - 在material-ui中的List中滚动到一个列表项
- php - 如何从存储为 json 的数据库中检索对象值
- javascript - 在下面的nodejs函数中apply和concat是什么意思,以及如何使用它?
- javascript - CSS - 无法解析本地 ttf 文件?
- javascript - 在类定义中使用后无法覆盖 mixin 行为
- c# - udpclient 仅在本地接收广播(c#,Unity)