0

recently I have been experimenting with boost::variant. I am attempting to apply arithmetic to two variant objects of types <int, float> as such:

typedef boost::variant<int, float> VariableValue;
VariableValue var1 = 2;
VariableValue var2 = 5;
VariableValue var3 = var1 + var2;
std::cout << "Result: " << var3 << std::endl; //expected 7

This should work for either alternative of the variant such as:

VariantValue var1 = 2;
VariantValue var2 = 1.234;
VariantValue var3 = var1 + var2;
std::cout << "Result: " << var3 << std::endl; //expected 3.234

However this approach is not working. I have been researching this issue and I have seen people using boost::apply_visitor and template to achieve similar results. How can I achieve my goal?

Rhathin
  • 1,176
  • 2
  • 14
  • 20
Tom
  • 1,235
  • 9
  • 22
  • Which alternative a variant holds is a run-time property. What type should `variant + variant` have? – Evg Dec 22 '19 at 13:58
  • The variant will hold either one depending on how to user specifies their input. I will update the question to reflect this. – Tom Dec 22 '19 at 14:01
  • Type of `var1 + var2` should be known at compile-time. But what a variant holds is known at run-time only. The compiler has to consider all possible alternatives. In the general case, the sum variant would consist of `N^2` types if you want to handle all possible combinations. The return type of a visitor cannot depend on which alternative a variant holds. – Evg Dec 22 '19 at 14:09
  • Take a look at [this question](https://stackoverflow.com/questions/59279624/how-do-i-solve-template-argument-deduction-substitution-failure-when-implement/59280029#59280029). – Evg Dec 22 '19 at 14:13

1 Answers1

0

I found the solution from the question How to simplify the plus action on boost variant? and simplified it for my purpose:

struct Add : public boost::static_visitor<VariableValue> {
    template <typename T, typename U>
    auto operator() (T a, U b) const -> decltype(a + b) {
        return a + b;
    }
};

To add:

VariantValue var1 = 2;
VariantValue var2 = 1.234;
std::cout << "Result: " << boost::apply_visitor(Add{}, var1, var2) << std::endl;

Outputs 3.234

Tom
  • 1,235
  • 9
  • 22