C ++ Шаблон для отображения типа структуры в enum? - PullRequest
2 голосов
/ 14 февраля 2011

У меня есть что-то вроде:

struct A { ... };
struct B { ... };
struct C { ... };

class MyEnum {
public:
    enum Value { a, b, c; }
}

template<typename T> MyEnum::Value StructToMyEnum();

template<>
MyEnum::Value StructToMyEnum<A>()
{
   return MyEnum::a;
}

template<>
MyEnum::Value StructToMyEnum<B>()
{
   return MyEnum::b;
}

Я в основном хочу получить a напрямую, вызывая что-то вроде

StructToMyEnum<A>();

Это лучшее, что я мог придумать, нопри компиляции я получаю multiple definition of 'MyEnum::Value StructToMyEnum<A>()' ошибок при попытке связать.

Какие-либо рекомендации по наилучшему способу сопоставления типов с перечислениями в соответствии с этим примером?

Ответы [ 3 ]

8 голосов
/ 14 февраля 2011

Вы можете сопоставить типы с перечислениями во время компиляции:

#include <iostream>

struct A { int n; };
struct B { double f; };
struct C { char c; };

class MyEnum
{
public:
    enum Value { a, b, c };
};

template<typename T> struct StructToMyEnum {};

template<> struct StructToMyEnum<A> {enum {Value = MyEnum::a};};
template<> struct StructToMyEnum<B> {enum {Value = MyEnum::b};};
template<> struct StructToMyEnum<C> {enum {Value = MyEnum::c};};

int main (int argc, char* argv[])
{
    std::cout << "A=" << StructToMyEnum<A>::Value << std::endl;
    return 0;
}
5 голосов
/ 14 февраля 2011

Множество определений объясняется тем, что вам нужно либо добавить ключевое слово inline, либо вставить реализацию ваших специализаций в файл cpp, оставив только объявления таких в заголовке.

Возможно, вы могли бы использовать mpl :: map для написания родовой версии. Примерно так:

struct A {};
struct B {};
struct C {};

enum Value { a,b,c };

template < typename T >
Value get_value()
{
  using namespace boost::mpl;
  typedef mpl::map
  < 
    mpl::pair< A, mpl::int_<a> >
  , mpl::pair< B, mpl::int_<b> >
  , mpl::pair< C, mpl::int_<c> >
  > type_enum_map;

  typedef typename mpl::at<type_enum_map, T>::type enum_wrap_type;

  return static_cast<Value>(enum_wrap_type::value);
}
3 голосов
/ 14 февраля 2011

Почему бы вам просто не сделать статическую переменную-член типа enum и добавить ее в свои структуры?

struct A
{
//Stuff

static MyEnum enumType; // Don't forget to assign a value in cpp
};

Чем вы можете просто сделать:

MyEnum e = StructA::enumType;

Или сделатьВы действительно хотите использовать шаблоны?

...