我有这段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.");