I am trying to find an elegant way to implement something like a very simple boost::mpl
type map.
Using MPL or any other boost
library is not an option in my context. Besides, the only operations I really need are initialization and lookup. Storing compile-time values would also be nice (which I could do using boost::fusion::set
, if I used a boost
-based solution).
I know how to do what I want with a traits class, but I think that the syntax is a bit too verbose and has some other small drawbacks, e.g. you can't define traits specializations inside a class declaration, and, well, generally it's not all neatly in one place.
Here's what I want to achieve using traits:
// base class definitions
class Foo {};
class Bar {};
class Baz {};
// traits base
template<typename T>
struct MyTraits {};
// traits specializations
template<>
struct MyTraits<Foo> {
static constexpr const char* name = "foo";
typedef double type;
};
template<>
struct MyTraits<Bar> {
static constexpr const char* name = "bar";
typedef std::string type;
};
// generic worker function
template<typename T>
void doStuff(const T& arg) {
std::cout << "got a " << MyTraits<T>::name << " - size: " << sizeof(typename MyTraits<T>::type) << std::endl;
}
int main(int, char*[]) {
Foo foo;
Bar bar;
Baz baz;
doStuff(foo);
doStuff(bar);
// this fails, as expected:
//doStuff(baz);
}
And here's the kind of syntax I would like to be able to use:
typedef TMapTemplate<
TMapEntry<Foo, double, "foo">,
TMapEntry<Bar, string, "bar">
> tTraitsMap;
// generic worker function
template<typename T>
void doStuff(const T& arg) {
std::cout << "got a " << at<tTraitsMap,T>::value<1>() << " - size: " << sizeof(at<tTraitsMap,T>::type<0>) << std::endl;
}
(Something like this would be ideal, but I would be happy with a simple one-to-one type map, really)