如何静态地断言是否定义了枚举常量?

问题描述 投票:2回答:1

我有这段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 被定义了吗?

c++ c++14 static-assert
1个回答
3
投票

和检测任何嵌套声明的方法一样。

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'");

0
投票

你可以使用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.");
© www.soinside.com 2019 - 2024. All rights reserved.