Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template argument deduction with strongly-typed enumerations

Tags:

If I have a normal (weak) enumeration, I can use its enumerated values as non-type template parameters, like so:

enum { Cat, Dog, Horse };  template <int Val, typename T> bool magic(T &t) {     return magical_traits<Val>::invoke(t); } 

and call it as: magic<Cat>(t)

as far as I can see, if I have a strongly-typed enumeration and don't want to hard-code the enumeration type, I end up with:

enum class Animal { Cat, Dog, Horse };  template <typename EnumClass, EnumClass EnumVal, typename T> bool magic(T &t) {     return magical_traits<EnumVal>::invoke(t); } 

and now I have to write: magic<Animal, Animal::Cat>(t), which seems redundant.

Is there any way to avoid typing out both the enum class and the value, short of

#define MAGIC(E, T) (magic<decltype(E), E>(T)); 
like image 601
Useless Avatar asked Feb 22 '12 18:02

Useless


People also ask

What is template argument deduction in C++?

Class Template Argument Deduction (CTAD) is a C++17 Core Language feature that reduces code verbosity. C++17's Standard Library also supports CTAD, so after upgrading your toolset, you can take advantage of this new feature when using STL types like std::pair and std::vector.

What is a strongly typed enum?

The strongly-typed enumerations have to follow stronger rules: The enumerators can only be accessed in the scope of the enumeration. The enumerators don't implicitly convert to int. The enumerators aren't imported in the enclosing scope. The type of the enumerators is by default int.

What are enumerations used for in C++?

In C++ programming, enum or enumeration is a data type consisting of named values like elements, members, etc., that represent integral constants. It provides a way to define and group integral constants. It also makes the code easy to maintain and less complex.

What is a deduction guide?

Template deduction guides are patterns associated with a template class that tell the compiler how to translate a set of constructor arguments (and their types) into template parameters for the class. The simplest example is that of std::vector and its constructor that takes an iterator pair.


2 Answers

You can do it like this, if you can use C++17

#include <type_traits>  enum class Animal { Cat, Dog, Horse };  template <typename EnumClass, EnumClass EnumVal>  void magic_impl() {     static_assert(std::is_same_v<EnumClass, Animal>);     static_assert(EnumVal == Animal::Cat); }  template <auto EnumVal> void magic() {     magic_impl<decltype(EnumVal), EnumVal>(); }  int main() {     magic<Animal::Cat>(); } 

demo: http://coliru.stacked-crooked.com/a/9ac5095e8434c9da

like image 113
Sopel Avatar answered Sep 24 '22 00:09

Sopel


I'm sorry, I have to tell you that

It is not possible

Take the macro, put it into a scary named header and protect it from your colleague's cleanup script. Hope for the best.

like image 42
Johannes Schaub - litb Avatar answered Sep 24 '22 00:09

Johannes Schaub - litb