Возможный передать имя как аргумент шаблону C++?

Это возможный записать класс:

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

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

5
задан Jon Seigel 12 April 2010 в 13:12
поделиться

2 ответа

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

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

#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 может здесь помочь.

5
ответ дан 14 December 2019 в 13:34
поделиться

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

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

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

1
ответ дан 14 December 2019 в 13:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: