Reputation: 607
consider the following code:
namespace fruit {
struct apple{
...
};
}
namespace language{
struct english{
...
};
}
I want to do something like:
std::unordered_map<std::string, ? > mymap = {
{"paul", {"like", fruit::apple} },
{"jonas", {"like", language::english} }
};
the key of my map is a string and the value should be such a pair <string, ? >
.
What type should I give as value for my map? I think things like union or functor can be used to solve the problem, but how? thanks in advance.
Upvotes: 1
Views: 1794
Reputation: 607
So I found a solution using 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))} }
};
thanks guys for your valuable suggestions.
Upvotes: 1
Reputation: 5166
Here's a snippet ( without the factory pattern => improve the syntax ) with proxy pattern so that you need not modify your existing objects:
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));
}
Upvotes: 2
Reputation: 44248
If you cannot use std::variant
or boost::variant
this solution could work:
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 ) ) {}
};
but most probably your problem has better solution.
Upvotes: 0
Reputation: 185
This code compiles for me:
#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()}}
};
}
Note that you may want to compile with something like -std=gnu++17
.
Upvotes: 1