Jos*_*eno 3 c++ enums types constraints type-traits
标题几乎是不言自明的。这是我的情况:
\n#include <type_traits>\n\nclass C1{\n enum{\n c1 = 3\n }\n}\n\nclass C2{\n enum{\n c2 = 10\n }\n}\n\ntemplate<class C>\nclass C3{\n void do_this();\n void do_that();\n\n void foo(){\n if constexpr(std::is_enum<C::c1>::value){\n do_this();\n }\n if constexpr(std::is_enum<C::c2>::value){\n do_that();\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n如果我尝试编译它,我会收到错误
\nerror: type/value mismatch at argument 1 in template parameter list for \xe2\x80\x98template<class _Tp> struct std::is_enum\xe2\x80\x99\nnote: expected a type, got \xe2\x80\x98typename C::c1\xe2\x80\x99\n\nerror: type/value mismatch at argument 1 in template parameter list for \xe2\x80\x98template<class _Tp> struct std::is_enum\xe2\x80\x99\nnote: expected a type, got \xe2\x80\x98typename C::c2\xe2\x80\x99\nRun Code Online (Sandbox Code Playgroud)\nstd::is_enum因此我的问题是:是否可以与未命名的一起使用enum?
绝对可以std::is_enum与未命名的枚举一起使用。
当前的实现中只有 2 个问题需要解决:
std::is_enum<C::c1>::value-C::c1是数据成员,但std::is_enum需要类型模板参数。decltype(...),例如std::is_enum<decltype(C::c1)>::valueC::c1C如果没有名为 的成员,将导致替换失败c1。所以对于 C++20 这可以工作:
template<class T>
concept is_enum_value = std::is_enum_v<T>;
template<class C>
struct C3 {
void foo() {
if constexpr(requires { { C::c1 } -> is_enum_value; }) {
do_this();
}
if constexpr(requires { { C::c2 } -> is_enum_value; }) {
do_that();
}
}
// ...
};
Run Code Online (Sandbox Code Playgroud)
如果C::c1和C::c2是互斥的(即每个类都C具有其中之一c1或c2两者都不存在 - 但绝不会同时c1存在两者),您可能会考虑使用尾随的 require 子句进行重载。c2foo
template<class C>
struct C3 {
void foo() requires requires { { C::c1 } -> is_enum_value; } {
// do_this implementation
}
void foo() requires requires { { C::c2 } -> is_enum_value; } {
// do_that implementation
}
};
Run Code Online (Sandbox Code Playgroud)
如果 C++20 不可用,您需要使用 SFINAE,这有点麻烦:
template<class T, class = void>
constexpr bool has_c1 = false;
template<class T>
constexpr bool has_c1<T, std::enable_if_t<std::is_enum_v<decltype(T::c1)>>> = true;
template<class T, class = void>
constexpr bool has_c2 = false;
template<class T>
constexpr bool has_c2<T, std::enable_if_t<std::is_enum_v<decltype(T::c2)>>> = true;
template<class C>
struct C3 {
void foo() {
if constexpr(has_c1<C>) {
do_this();
}
if constexpr(has_c2<C>) {
do_that();
}
}
// ...
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
391 次 |
| 最近记录: |