I'm trying to have my Variant type, a wrapper around c++17's std::variant, implicitly convert between types where appropriate. For instance, a char to std::string, or int to unsigned long. Here's my code:
#include <variant>
using variant_t = std::variant<
std::monostate,
std::string, bool, std::int32_t,
std::uint32_t, std::int64_t, std::uint64_t,
float, double, char, unsigned char,
std::vector<double>>;
class Variant : public variant_t {
public:
using variant::variant;
enum TypeId {
EMPTY = 0, // std::monostate. Empty is default when variant instantiated with nothing
STRING = 1,
BOOL = 2,
INT32 = 3,
UINT32 = 4,
INT64 = 5,
UINT64 = 6,
FLOAT = 7,
DOUBLE = 8,
CHAR = 9,
UCHAR = 10,
DOUBLEVECTOR = 11
};
TypeId type() const {
return (Variant::TypeId) index();
}
template<class VariantType>
VariantType get() const {
return std::get<VariantType>(*this);
}
};
What I want to be able to do is this:
TEST(VariantTests, HowToConvertIntToULongWithoutManualCast) {
Variant v(11);
ASSERT_EQ(v.type(), Variant::TypeId::INT32); // (pass, v is an int)
unsigned long toUnsignedLong = v; // error
long toLong = v; // error
// and any other conversions from int that make sense
}
How can I modify my Variant to support implicit type conversion?
Edit
As per the comments, I also need to account for incompatible pairs as well as compatible ones, e.g. the following would fail.
Variant v(12); // variant containing an int
std::string x = v; // should error, int to string incompatible