Можно передать имя в качестве аргумента в шаблон C ++? - PullRequest
5 голосов
/ 19 февраля 2010

Можно ли написать класс:

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

В принципе, я хочу иметь возможностьукажите не только тип, но и имя переменных-членов.

Ответы [ 2 ]

5 голосов
/ 19 февраля 2010

Это невозможно, вам приходится прибегать к решениям на основе макросов или использовать предопределенный набор типов, которые предоставляют именованные элементы.

Возможный подход на основе макросов:

#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 голос
/ 19 февраля 2010

Нет, это невозможно. Существует конструкция под названием typelist , которая может быть использована для того, чтобы добиться такого эффекта, как вы. К сожалению, даже тогда вы не получите именованных членов, вы получите функции доступа с именами, такими как MyClass::getField<1>().

В C ++ 0x вы можете добиться большего успеха, чем списки типов с шаблонами с переменными значениями . Но у вас все равно будут функции доступа, которые выглядят так же, как и в случае с C ++.

Заманчиво привести здесь пример шаблона с вариадностью, потому что он не будет слишком большим. К сожалению, я думаю, что для того, чтобы сделать это хорошо, потребовалось бы несколько часов исследований с моей стороны, чтобы точно узнать, как работают вариационные шаблоны. Я мог бы сделать глупую версию относительно легко, но я ожидаю, что глупая версия будет намного менее приятной во многих отношениях, чем хорошо сделанная версия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...