How to combine templates with enums in C ++?

The C ++ programming language has a huge collection of functions that provides strict control over data types. Often its code was generated using a template system to achieve the most adequate functionality, while guaranteeing the correct type preservation and flexibility in its manipulation. Less often, enumerations are used for this purpose, because they allow you to define explicit possibilities for the data and do not have a direct way to check the correctness of the type.

So, we have templates that allow functions and classes to work with generic types without overwriting each of them; and enumerations providing direct use of the expected types.

Is it possible to define a limited template architecture for a class using an enumeration as a model? How does a template method use an enumerated type and when can it be useful?

My last question: how to combine patterns and enumeration types and use them together in an abstract data design?

As an example, suppose you are trying to create a data container that you expect to have types defined in an enumeration in your class:

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

You also defined each of the types present in the class element :

 class text; class widget; class image; 

When creating an element, you want to specify its type of content (text, widget or image) in order to pass it by the template argument.

 if (node_type == text_type) do_something(); 

In Java, do you have List<? extends T> List<? extends T> , which implicitly says what type of classes can be used as a template parameter. Can this be done in C ++ using enums? How to work with enumerated types in operators?

Question I would like to know how to limit the behavior of templates to enumerated types, to ensure that they are used, and to orient the code using the traditional way of working with enums.

+4
source share
2 answers

A hierarchy of type attributes, like @UncleBens, illustrates a common way to solve this problem.

You can attach information to classes using the static const members of an integer or enumerated type.

 #include <iostream> enum color { red, green, blue }; struct x { static const color c = red; }; template< color c > struct thing; template<> struct thing< red > { thing() { std::cout << "red\n"; } }; int main() { thing< x::c >(); } 
+6
source

If you do not need to use enumerations, I believe that you can use similar methods used in the standard library to categorize iterators.

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

Another possibility: overloading foo_implementation for other categories of elements.

+6
source

All Articles