如果我有一个普通(弱)枚举,我可以使用它的枚举值作为非类型模板参数,如下所示:
enum { Cat, Dog, Horse };
template <int Val, typename T> bool magic(T &t)
{
return magical_traits<Val>::invoke(t);
}
并将其命名为:magic<Cat>(t)
据我所知,如果我有一个强类型的枚举,并且不想硬编码枚举类型,我最终得到:
enum class Animal { Cat, Dog, Horse };
template <typename EnumClass, EnumClass EnumVal, typename T> bool magic(T &t)
{
return magical_traits<EnumVal>::invoke(t);
}
现在我必须写:magic<Animal, Animal::Cat>(t)
,这似乎是多余的。
有没有办法避免输入枚举类和值,缺少
#define MAGIC(E, T) (magic<decltype(E), E>(T));
答案 0 :(得分:13)
对不起,我得告诉你那个
获取宏,将其放入一个可怕的命名标题中,并保护它不受同事的清理脚本的影响。希望最好的。
答案 1 :(得分:11)
如果你可以使用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>();
}
答案 2 :(得分:2)
如果你只对enum
的值感兴趣,而不是它的类型,你应该能够使用constexpr
函数将值转换为整数,避免重复类型名。
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);
但是,正如其他人已经指出的那样,如果你想让它依赖于类型,它也行不通。
答案 3 :(得分:0)
这个问题有accepted answer(upvoted)。
在重构我自己的代码时,我想出了一个更完整的解决方案:
第1步:使用我写的代码:
timer1.Start();
第2步:客户代码:
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; }
};