模板参数的变量名?

Rob*_*son 6 c++ generics templates

有没有办法根据template参数在类中生成变量的名称?

template<class T, (someconstruct) t>

class Item {
    public:        
        T t;
};

Item<float, "Position"> myItem;

myItem.Position = 0.123f;
Run Code Online (Sandbox Code Playgroud)

这样我实例化的是一个类型的变量T,带有标识符t(t由程序员传入的地方,也就是说Position,我们有一个T被调用的Position?或者这是否将模板元编程概念拉得太远了?:p

Edw*_*nge 6

不,不是那种语法,但你可以创建一个类似于你想要做的设置:

template < typename Field >
struct field_value
{
  typename Field::type value;
};

template < typename Seq >
struct funky_struct : boost::mpl::inherit_linearly
  <
    Seq
  , boost::mpl::inherit
    <
      field_value< boost::mpl::placeholders::_2>
    , boost::mpl::placeholders::_1
    >
  >::type
{};

template < typename Field, typename Struct >
typename Field::type & get(Struct & s) { return static_cast< field_value<Field>& >(s).value; }

struct first_field { typedef int type; };
struct second_field { typedef char type; };

struct my_funky : funky_struct< boost::mpl::vector<first_field,second_field> > {};

...
my_funky f;
get<first_field>(f) = 23;
Run Code Online (Sandbox Code Playgroud)

我留下允许非默认构造给你.此外,通过少量工作,这可以反映出来,您可以在其中粘贴任何有用的信息.


Cha*_*via 5

不,你无法通过模板实现这一目标.变量名称(称为"标识符")不能由模板以编程方式操作.只有预处理器才能做到这一点.

无论如何,这似乎是一个坏主意.你为什么这么做?


jxh*_*jxh 5

你想要实现的东西可以通过继承来完成.也就是说,父类具有您希望模板具有的变量名称.

struct ItemNull {};

template <typename X, typename Y = ItemNull>
class Item : public X, public Y {};

template <typename T> struct HasPosition { T Position; };
template <typename T> struct HasMomentum { T Momentum; };

Item< HasPosition<float> > myItem1;
myItem1.Position = 0.123f;

Item< HasPosition<float>, HasMomentum<float> > myItem2;
myItem2.Position = 0.1f;
myItem2.Momentum = 0.2f;
Run Code Online (Sandbox Code Playgroud)

可选的第二个参数允许合成,如图所示myItem2.要添加第三个字段,您可以添加到尾部,或从前面展开:

template <typename T> struct HasName { T Name; };

Item <
    HasPosition<float>,
    Item< HasMomentum<float>, HasName<std::string> >
> myItem3;
myItem3.Position = 0.1f;
myItem3.Momentum = 0.2f;
myItem3.Name = "Adam";

Item <
    Item < HasPosition<float>, HasMomentum<float> >,
    HasName<std::string>
> myItem4;
myItem4.Position = 0.1f;
myItem4.Momentum = 0.2f;
myItem4.Name = "Adam";
Run Code Online (Sandbox Code Playgroud)

我个人倾向于前两种方法,因为我发现它是一种更直观的方式,可以将它扩展到3个以上的领域.该Item模板语法大概可以使用可变参数模板参数进行简化.

Has...模板可以被机器生成或者可以创建一个宏,使添加新字段一个相对简单的任务.

#define MAKE_HAS(X) template <typename T> struct Has##X { T X; }

MAKE_HAS(Position);
MAKE_HAS(Momentum);
MAKE_HAS(Name);
Run Code Online (Sandbox Code Playgroud)