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));
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.
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.
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.
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.
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
I'm sorry, I have to tell you that
Take the macro, put it into a scary named header and protect it from your colleague's cleanup script. Hope for the best.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With