可以将name作为参数传递给c ++模板吗?

时间:2010-02-19 00:37:49

标签: c++ templates

是否可以写一个课程:

template<typename T, ... name> struct Magic {
  T name;
};

这样:

Magic<int, foo> gives:

Magic<int, foo> {
  int foo;
}

Magic<float, bar> gives:

Magic<float, bar> {
  float bar;
}

基本上,我希望不仅能够指定Type,还能指定成员变量的名称。

2 个答案:

答案 0 :(得分:5)

这是不可能的,您必须使用基于宏的解决方案或使用提供命名成员的预定义类型集。

一种可能的基于宏的方法:

#define MAGIC(name_) \
    template<typename T> struct Magic1 { \
        T name_; \
    };

MAGIC(foo);

或:

#define MAGIC(type_, name_) \
    struct Magic1 { \
        type_ name_; \
    };

MAGIC(foo);

使用预处理器魔法,例如利用Boost.Preprocessor,您应该能够以更方便的方式生成 n 命名成员。

另一种方法可能是使用一组预定义的类来提供您继承的某些命名成员:

enum { MemberNameFoo, MemberNameBar };

template<class T, int id>
struct named_member;

template<class T>
struct named_member<T, MemberNameFoo> {
    T foo;
};

template<class T>
struct named_member<T, MemberNameBar> {
    T bar;
};

// holder for the above, just one member for this example:

template<class T, int name>
struct holder : named_member<T, name> {};

// using it:

typedef holder<int, MemberNameFoo> HasFoo;
typedef holder<int, MemberNameBar> HasBar;

使用编译时列表,您可以继承 n named_member实例,Boost.MPL可以在这里提供帮助。

答案 1 :(得分:1)

不,这是不可能的。有一个名为typelist的结构可以用来实现像你一样的效果。不幸的是,即使这样你也不会得到命名成员,你将获得名为MyClass::getField<1>()的访问函数。

在C ++ 0x中,您可以比使用variadic templates的列表更好。但是你仍然会有类似C ++案例的访问器函数。

在这里放下一个可变参数模板示例很诱人,因为它不会太大。不幸的是,我认为做得好将需要花费几个小时的时间研究,以确切了解可变参数模板的工作原理。我可以相对容易地做一个愚蠢的版本,但我希望这个愚蠢的版本在各种方面都不会比做得好的版本好很多。