0

I am trying to identify the type of a boost::variant within a class object to perform the associated member functions. Consider the following code:

#include <cstdio>
#include <cassert>
#include <iostream>
#include <boost/variant.hpp>
#include <string>
using namespace std;

typedef boost::variant< string, double> Variant;

class test{ 
  public:
    void func1 (Variant V); 
    void func2 (string s); 
    void func3 (double d);
    struct my_visitor : public boost::static_visitor<> {
      test &my_test;
      my_visitor(test &arg) : my_test(arg) {}

      void operator()( string s ) { my_test.func2(s); }
      void operator()( double d ) { my_test.func3(d); }
      //... for each supported type
    };

}; 


void test::func1(Variant V){
  boost::apply_visitor( my_visitor(*this),V);
}

void test::func2( string s){ cout << "func3" << endl;}
void test::func3(double d){ cout << "func4" << endl;}

int main (){
    test t;
    Variant V = 3.1;
    t.func1(V); 
    V = "hello"; 
    t.func1(V);
}

The issue is I need to identify the type of Variant within a member function to call the related member function for that data type EVEN within the same object.

Richard
  • 56,349
  • 34
  • 180
  • 251
sam
  • 43
  • 1
  • 5

1 Answers1

3

The question is not quite clear, but are you perhaps looking for this?

class test {
  //...

struct my_visitor : public boost::static_visitor<> {
  test &my_test;
  my_visitor(test &arg) : my_test(arg) {}

  void operator()( string s ) const { my_test.func3(s); }
  void operator()( double d ) const { my_test.func4(d); }
  //... for each supported type
};

  //...
};


test::func1(Variant V) {
  boost::apply_visitor(my_visitor(*this), V);
}

EDIT Added const qualifiers to operator() to allow using temporaries of my_visitor in apply_visitor().

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • If the functions func1, func2, func3 have another argument, lets say `func1( V, Object obj)`, ``func2( V, Object obj),... How could I pass the second argument into my_visitor() since it accepts only one argument. Am I right? – sam Nov 28 '12 at 10:50
  • 1
    @sam In such case, you can simply add any number of constructor arguments and member variables to `my_visitor` to send all required data from `my_visitor` creation to the functions it calls. – Angew is no longer proud of SO Nov 28 '12 at 10:56
  • I tried yet to compile an example implemented the above visitation class. The code is edited in the main post. However, I got an error by compiling refer to the apply_visitor. Could you try to compile it and guess what is gone wrong, Since this solution is exactly what I want to achieve. – sam Nov 28 '12 at 11:31
  • 1
    @sam When the visitor is created as a temporary (unnamed), it's passed by const-reference (non-const references can't bind to a temporary), so the `operator()` member functions of the visitor have to be declared as `const`. I've edited my answer accordingly. BTW, when asking about a compilation error, post the actual error message. – Angew is no longer proud of SO Nov 28 '12 at 13:04