I was trying to create something like the upcoming (if ever) std::expected using std::variant. I thought it would be very easy to something like that, yet maybe not optimal.
However, I faced some interesting exercise with std::variant and it is how to assign a value by an index? The only way how I got close to it is in the example below, which is maybe not too bad at the end, but still, looks quite weird at first glance. (yet I am not sure if it's general enough)
#include <variant>
template<typename ValueType, typename ErrorType>
class Expected
{
std::variant<std::monostate, ValueType, ErrorType> data_;
public:
const ValueType& GetValue()
{
return std::get<1>(data_);
}
void SetValue(auto&& value)
{
data_ = decltype(data_)(std::in_place_index_t<1>{}, std::forward<decltype(value)>(value));
}
};
int main()
{
Expected<bool, bool> e;
e.SetValue(false);
return e.GetValue();
}
I also got an idea that some really thin wrapper class could help here, I suppose it could be written in a way, that it would be optimized out by the compiler.
std::variant<std::monostate, ValueWrapper<ValueType>, ErrorType> data_;
The function you're looking for is variant::emplace
. Your function becomes:
void SetValue(auto&& value)
{
data_.template emplace<1>(std::forward<decltype(value)>(value));
}