如果所有选项都满足一个接口,可以使用boost变型进行类型擦除吗?

时间:2018-07-05 18:31:15

标签: c++ boost-variant

我有一些代码,其中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;
}

1 个答案:

答案 0 :(得分:2)

您可能会使用类似的内容:

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();