I've been reading all the other questions related to this error and could not find something suitable to my case (or I did not understood them correctly).
I present a minimal example of a class holding a std::variant which represents a variant value (the exception and error handling is omited for brevity):
#include <iostream>
#include <variant>
#include <string>
class Value {
public:
Value(const std::string&);
Value(const int&);
template<typename T> const T& GetValue() const;
private:
std::variant<int, std::string> m_value;
};
Value::Value(const std::string& val):m_value(val) {}
Value::Value(const int& val):m_value(val) {}
template<> const int& Value::GetValue<int>() const {
return std::get<int>(m_value);
}
template<> const std::string& Value::GetValue<std::string>() const {
return std::get<std::string>(m_value);
}
int main() {
Value v_int { 666 };
Value v_str { "Hola" };
// int i = v_int.GetValue(); // ERROR
int i = v_int.GetValue<int>(); // OK but not desireable
// std::string s = v_str.GetValue(); // ERROR
std::string s = v_str.GetValue<std::string>(); // OK but not desireable
std::cout << "i: " << i << " s: " << s << std::endl;
return 0;
}
What I don't understand is why the // ERROR
calls are not deductible if int
and std::string
are not convertible to each other and target variable destination is the correct type.
Even if manually calling GetValue<T>
that would defy the purpose of the wrapping class.
Is calling the non explicit version even possible? Please, if possible do not limit to just present a solution but it would be appreciated an explanation of why it is not working so I can learn from my mistakes.
You might use conversion operator:
class Value {
public:
Value(const std::string&);
Value(const int&);
auto GetValue() const
{
struct {
const std::variant<int, std::string>& m_value;
operator int() const { return std::get<int>(m_value); }
operator const std::string&() const { return std::get<std::string>(m_value); }
} w{m_value};
return w;
}
private:
std::variant<int, std::string> m_value;
};
But not sure it is a good idea.