Как объединить шаблоны с перечислениями в C ++? - PullRequest
4 голосов
/ 19 октября 2010

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

Итак, у нас есть шаблоны, которые позволяют функциям и классам работать с универсальными типами, не переписываясь для каждого; и перечисления, обеспечивающие прямое использование ожидаемых типов.

Можно ли определить архитектуру ограниченного шаблона для класса, используя enum в качестве модели? Как шаблонизированный метод может использовать enumed type и когда он может быть полезен?

Мой последний вопрос: как соединить шаблоны и типы перечисления и использовать их вместе в абстрактном дизайне данных?

В качестве примера предположим, что вы пытаетесь создать контейнер данных, для которого ожидаются типы, определенные в перечислении в вашем классе:

template <typename T>
class element
{
public:
  enum type { text_type, widget_type, image_type };

  ...
private:
  type node_type;

};

Вы также определили каждый из типов, представленных в class element:

class text;
class widget;
class image;

Создавая элемент, вы хотите указать его тип содержимого (текст, виджет или изображение), чтобы передавать его по аргументу шаблона.

if (node_type == text_type) do_something();

В Java у вас есть List<? extends T>, который неявно говорит, какой тип классов можно использовать в качестве параметра шаблона. Можно ли это сделать в C ++, используя перечисления? Как работать с перечисляемыми типами в операторах?

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

Ответы [ 2 ]

6 голосов
/ 19 октября 2010

Типовая черта характера, как показывает @UncleBens, является обычным способом решения этой проблемы.

Вы можете присоединять информацию к классам, используя также static const члены целочисленного типа или типа перечисления.1005 *

6 голосов
/ 19 октября 2010

Если вам не нужно использовать перечисления, я полагаю, что вы можете использовать аналогичные методы, используемые в стандартной библиотеке для классификации итераторов.

class text {};
class widget {};
class image {};

struct text_type_tag {};
struct widget_type_tag {};
struct image_type_tag {};

template <class T>
struct element_traits;

template <>
struct element_traits<text>
{
    typedef text_type_tag category;
};

template <>
struct element_traits<widget>
{
    typedef widget_type_tag category;
};

template <>
struct element_traits<image>
{
    typedef image_type_tag category;
};

//add specializations for any other type you want to categorize

//a template that only works with widget types
template <class Widget>
void foo_implementation(Widget w, widget_type_tag);

template <class Widget>
void foo(Widget w)
{
    foo_implementation(w, typename element_traits<Widget>::category());
}

int main()
{
    foo(widget());
    foo(10);  //error, element_traits not specialized for int (incomplete)
    foo(image()); //error, no matching call for foo_implementation(image, image_type_tag);
}

Еще одна возможность с этим: перегрузка foo_implementation для другихкатегории элементов.

...