Suppose I have a struct MyMap
, which is a wrapper for std::map
where value type is std::variant<A, B>
but A and B behave completely different (they have different member functions and fields, and share no common functionality).
For example:
#include <map>
#include <variant>
#include <string>
struct A {
std::string val;
};
struct B {
int val;
};
struct MyMap {
std::map<int, std::variant<A, B>> internalMap;
};
I want to implement an operator[]
overload for MyMap
such that the type of the accesed element is the actual type A
or B
.
To clarify further, i DO NOT want this:
std::variant<A, B> operator[](int key) { return internalMap[key]; }
, but I want something like:
// If I have:
MyMap m;
m.internalMap[1] = A{};
m.internalMap[2] = B{};
// I want the type of internalMap[1] to be A, and type of internalMap[2] to be B:
A a = m.internalMap[1];
B b = m.internalMap[2];
I want to be able to call methods specific to type A
or type B
after accessing them with this operator[]
overload.
Should this type deduction happen at runtime or at compile time (and how)?
struct AorB : public std::variant<A, B> {
using std::variant<A, B>::variant;
operator A&() {return std::get<A>(*this);}
operator const A&() const {return std::get<A>(*this);}
operator B&() {return std::get<B>(*this);}
operator const B&() const {return std::get<B>(*this);}
};
And then you store this as the value of the map. Then, you can pass this to methods expecting an A
or a B
, and it works, as long as it's unambiguous.
A a = m.internalMap[1]; //no problem!
B b = m.internalMap[2];