构造一个 unordered_map ,值为一对字符串和对象类型

construct an unordered_map with value being a pair of string and object type

考虑以下代码:

namespace fruit {
    struct apple{
        ...
    };
}

namespace language{
    struct english{
        ...
    };
}

我想做这样的事情:

std::unordered_map<std::string, ? > mymap = { 
    {"paul", {"like", fruit::apple} },
    {"jonas", {"like", language::english} }
};

我的map的key是一个字符串,value应该是这样一对<string, ? >.
我应该为我的地图赋予什么类型的价值?我认为可以使用 union 或 functor 之类的东西来解决问题,但是如何呢?提前致谢。

这段代码为我编译:

#include <unordered_map>
#include <utility>
#include <variant>

namespace fruit {
   struct apple{};
}

namespace language{
   struct english{};
}

int main(){
    std::unordered_map<std::string,std::pair<std::string,std::variant<fruit::apple, language::english> > > mymap { 
        {"paul", {"like", fruit::apple()} },
        {"jonas", {"like", language::english()}}
    };
}

请注意,您可能希望使用 -std=gnu++17.

之类的内容进行编译

如果您不能使用 std::variantboost::variant,此解决方案可能有效:

struct data {
    std::string action;
    std::unque_ptr<fruit::apple> apple;
    std::unque_ptr<language::english> english;

    data( std::string act, fruit::apple ap ) : 
        action( std::move( act ) ), 
        apple( std::make_unqiue<fruit::apple>( std::move( ap ) ) {}
    data( std::string act, language::english en ) : 
        action( std::move( act ) ), 
        english( std::make_unqiue<language::english>( std::move( en ) ) {}
};

但很可能您的问题有更好的解决方案。

这是一个带有代理模式的片段(没有工厂模式 => 改进语法),因此您无需修改​​现有对象:

struct base {
};

namespace fruit {
    struct apple {};
    struct apple_proxy: base {
        apple_proxy()
            :apple_ptr(make_shared<fruit::apple>())
        {}
        shared_ptr<apple> apple_ptr;
    };
}

namespace language {
    struct english {};
    struct english_proxy : base {
        english_proxy()
        :english_ptr(make_shared<language::english>())
        {}
        shared_ptr<english> english_ptr;
    };
}

int main() {
    std::unordered_map<std::string, shared_ptr<base>> map;

    shared_ptr<fruit::apple_proxy> a = make_shared<fruit::apple_proxy>();
    map.emplace(make_pair("apple",a));

    shared_ptr<language::english_proxy> e = make_shared<language::english_proxy>();
    map.emplace(make_pair("english", e));
}

所以我找到了使用 std::type_index 的解决方案。

typedef std::pair<std::string, std::type_index> myPair;

std::unordered_map<std::string, myPair> myMap =
{
    {"paul", {"likes", std::type_index(typeid(fruit::apple))} },
    {"jonas",  {"likes", std::type_index(typeid(language::english))} }
};

感谢大家的宝贵建议。