代码之家  ›  专栏  ›  技术社区  ›  Carbon

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

  •  1
  • Carbon  · 技术社区  · 6 年前

    我有一些代码,其中boost::variant中的每个元素都实现一个公共接口。出于各种原因,我不想将它们存储为已擦除类型。有没有一种简单的方法可以在给定变量的情况下,不必为每个可能的情况编写访问者就可以访问接口?我在下面得到的具体错误都在cast line上,如下所示:

    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 回复  |  直到 6 年前
        1
  •  2
  •   Jarod42    6 年前

    你可能会用到:

    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();
    
    推荐文章