如果定义了枚举常量,如何静态断言?
How to statically assert if enumeration constant is defined?
我有这个 C++14 代码:
#include <type_traits>
struct f1 {
enum struct e { a };
};
struct f2 {
enum struct e {};
};
template <typename T>
struct my_struct {
using e = typename T::e;
my_struct()
: _e{e::a} {} // e::a used here
e _e;
};
int main() {
my_struct<f1> a;
my_struct<f2> b; // compilation fails
}
很明显,编译失败了 'a' is not a member of 'my_struct<f2>::e'
。我真的很想向 my_struct
添加一些静态断言,以添加自定义错误消息。首先,我可以检查 e
是否实际上是一个枚举:
static_assert(std::is_enum<e>::value, "my message");
那么,我应该添加什么来静态断言 e::a
已定义?
与检测任何嵌套声明的方式相同:
template <typename T, typename = void>
struct enum_defines_a : std::false_type {};
template <typename T>
struct enum_defines_a<T, decltype(void(T::a))> : std::is_enum<T> {};
static_assert(enum_defines_a<e>::value, "Enum doesn't define 'a'");
您可以使用 SFINAE 来解决这个问题。考虑以下代码:
template <class T>
class has_a
{
template <class C>
static std::true_type test(C, C = C::a);
template <class C>
static std::false_type test(...);
public:
using type = T;
static bool constexpr value = decltype(test<T>(T{}))::value;
};
然后,您可以:
static_assert(has_a<e>::value, "Given type is incorrect.");
我有这个 C++14 代码:
#include <type_traits>
struct f1 {
enum struct e { a };
};
struct f2 {
enum struct e {};
};
template <typename T>
struct my_struct {
using e = typename T::e;
my_struct()
: _e{e::a} {} // e::a used here
e _e;
};
int main() {
my_struct<f1> a;
my_struct<f2> b; // compilation fails
}
很明显,编译失败了 'a' is not a member of 'my_struct<f2>::e'
。我真的很想向 my_struct
添加一些静态断言,以添加自定义错误消息。首先,我可以检查 e
是否实际上是一个枚举:
static_assert(std::is_enum<e>::value, "my message");
那么,我应该添加什么来静态断言 e::a
已定义?
与检测任何嵌套声明的方式相同:
template <typename T, typename = void>
struct enum_defines_a : std::false_type {};
template <typename T>
struct enum_defines_a<T, decltype(void(T::a))> : std::is_enum<T> {};
static_assert(enum_defines_a<e>::value, "Enum doesn't define 'a'");
您可以使用 SFINAE 来解决这个问题。考虑以下代码:
template <class T>
class has_a
{
template <class C>
static std::true_type test(C, C = C::a);
template <class C>
static std::false_type test(...);
public:
using type = T;
static bool constexpr value = decltype(test<T>(T{}))::value;
};
然后,您可以:
static_assert(has_a<e>::value, "Given type is incorrect.");