template argument deduction with strongly-typed enumerations

天涯浪子 提交于 2019-11-30 00:07:22

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

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.

If you're only interested in the enum's value, and not its type, you should be able to use a constexpr function to convert the value to an integer, avoiding repeating the type name.

enum class Animal { Cat, Dog, Horse };

template <typename T> constexpr int val(T t)
{
    return static_cast<int>(t);
}

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

magic<val(Animal::Cat)>(t);

However, as pointed out already by others, if you want to make this depend on the type as well, it will not work.

This question has an accepted answer (upvoted).

While refactoring my own code, I figured out a more complete solution:

Step 1: using code I was writing:

template<typename V, typename EnumClass, EnumClass Discriminator>
class strong_type final // type-safe wrapper for input parameters
{
    V value;
public:
    constexpr explicit strong_type(V x): value{x} {}
    constexpr auto get() const { return value; }
};

Step 2: client code:

enum class color { red, green, blue, alpha };

// the part OP was asking about:
template<color C>
using color_channel = strong_type<std::uint8_t, color, C>;

using red = color_channel<color::red>; // single argument here
using green = color_channel<color::green>;
using blue = color_channel<color::blue>;
using alpha = color_channel<color::alpha>;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!