如何测试另一个类中的类型是否存在?

Adr*_*ian 4 c++ sfinae type-traits template-meta-programming c++14

我想我可以测试(使用 C++14)一个类是否包含一个类型,我可以这样做:

#include <type_traits>

struct X {
  using some_type = int;
};
struct Y {};

template <typename T, typename = void>
struct has_some_type : std::false_type {};

template <typename C>
struct has_some_type<C, typename C::some_type> : std::true_type {};

static_assert(has_some_type<X>::value); // unexpectedly fails
static_assert(has_some_type<Y>::value); // correctly fails
Run Code Online (Sandbox Code Playgroud)

static_assert失败了,这让我感到惊讶,因为检查成员函数将以类似的方式工作。

#include <type_traits>

struct X {
  void some_function();
};
struct Y {};

template <typename T, typename = void>
struct has_some_function : std::false_type {};

template <typename C>
struct has_some_function<C, decltype(std::declval<C>().some_function())> : std::true_type {};

static_assert(has_some_function<X>::value); // correctly succeeds
static_assert(has_some_function<Y>::value); // correctly fails
Run Code Online (Sandbox Code Playgroud)

为什么这不起作用?我如何测试一个类是否有类型?

小智 5

我知道这个问题被标记为 C++14,但为了其他人登陆这里:

在 C++20 及更高版本中,概念提供了一种干净的语法(更不用说在许多情况下也消除了对static_assert和 的需要enable_if)来检查类型是否具有给定的类型成员:

template<typename T>
concept has_some_type = requires {
  typename T::some_type;
};

struct X {
  using some_type = int;
};
struct Y {};

static_assert(has_some_type<X>); 
static_assert(!has_some_type<Y>);
Run Code Online (Sandbox Code Playgroud)