I am using boost fusion. I want to declare a template function that assigns to a field of a map and performs various other functions. I cannot for the life of me work out how to get the type of an element stored in a fusion::map. I am sure it is possible - I just can't fathom the documentation. I think I have two problems:
To keep this really specific a minimal test case is shown below.
#include <string>
#include <boost/shared_ptr.hpp>
#include <boost/fusion/include/container.hpp>
#include <boost/fusion/container.hpp>
#include <boost/fusion/iterator.hpp>
using std::string;
using namespace boost;
namespace fields {
struct rgb;
struct gray;
struct keypoints;
struct edges;
struct objects;
}
typedef fusion::map<
fusion::pair<fields::rgb, string>,
fusion::pair<fields::gray, int>,
fusion::pair<fields::keypoints, int>,
fusion::pair<fields::edges, int>,
fusion::pair<fields::objects, double>
> Fields;
Fields A_map;
template<typename field>
void Add(fusion::result_of::value_of_data<field> data) {
fusion::at_key<field>(A_map) = data;
}
int main() {
Add<fields::gray>(123);
}
The function Add should be declared to receive an argument which is the type of the gray field (int in the example).
@jv yes that is exactly the answer. Thanks very much.
I've only being using fusion for a few hours and had not found that in the documentation (because the functions on iterators are visible at the top-level, whereas value_at_key only shows up when you dig down into Sequence/intrinsic/metafunctions)
Also I needed to use typename and settled for simpler includes. The corrected code is:
#include <string>
#include <boost/fusion/include/sequence.hpp>
#include <boost/fusion/include/map.hpp>
using std::string;
using namespace boost;
namespace fields {
struct rgb;
struct gray;
struct keypoints;
struct edges;
struct objects;
}
typedef fusion::map<
fusion::pair<fields::rgb, string>,
fusion::pair<fields::gray, int>,
fusion::pair<fields::keypoints, int>,
fusion::pair<fields::edges, int>,
fusion::pair<fields::objects, double>
> Fields;
Fields A_map;
template<typename field>
void Add(typename fusion::result_of::value_at_key<Fields, field>::type data) {
fusion::at_key<field>(A_map) = data;
}