【问题标题】:C++ Template for mapping struct type to enum?用于将结构类型映射到枚举的 C++ 模板?
【发布时间】:2011-02-14 17:43:36
【问题描述】:

我有类似的东西:

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&lt;A&gt;()' 错误。

对于根据此示例将类型映射到枚举的最佳方法有什么建议吗?

【问题讨论】:

  • 您为什么要这样做的任何特殊原因?对我来说,它增加了不必要的复杂性,我无法弄清楚这个模型会完成哪些现有模型无法做到的事情,并且做得更好。
  • 听起来像是缺少标题保护。
  • 您需要内联模板函数的完整专业化。

标签: c++ templates enums map struct


【解决方案1】:

您可以在编译时将类型映射到枚举:

#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;
}

【讨论】:

  • 我也喜欢这种方法!
【解决方案2】:

多个定义是因为您需要添加 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);
}

【讨论】:

  • 我不使用 boost,但您的内联建议有效。由于某种原因,我忘记添加该修饰符,并且还认为模板函数需要在标题中实现。
  • @chriskirk - 他们做到了。模板函数的特化不是模板函数。
【解决方案3】:

您为什么不直接创建一个枚举类型的静态成员变量并将其添加到您的结构中?

struct A
{
//Stuff

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

比你能做到的:

MyEnum e = StructA::enumType;

或者你真的想使用模板吗?

【讨论】:

  • 我想稍微解耦映射。我喜欢你的建议,不过我会牢记在心。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 1970-01-01
  • 2019-04-09
  • 2017-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多