检查是否在可变参数模板参数包中传递了类型

qiu*_*bit 8 c++ templates type-traits c++17

我听说过,使用新的C++ 1z语法,很容易检查是否在可变参数模板参数包中传递了一个类型 - 显然你可以使用接近一行长的代码来做到这一点.这是真的?那些相关的功能是什么?(我尝试通过折叠表达式查看但我无法看到如何在该问题中使用它们...)

以下是我在C++ 11中解决问题的方法,以供参考:

#include <type_traits>


template<typename T, typename ...Ts>
struct contains;

template<typename T>
struct contains<T> {
    static constexpr bool value = false;
};

template<typename T1, typename T2, typename ...Ts>
struct contains<T1, T2, Ts...> {
    static constexpr bool value = std::is_same<T1, T2>::value ? true : contains<T1, Ts...>::value;
};
Run Code Online (Sandbox Code Playgroud)

Pra*_*ian 27

你在找std::disjunction.它在N4564 [meta.logical]中指定.

#include <type_traits>

template<typename T, typename... Ts>
constexpr bool contains()
{ return std::disjunction_v<std::is_same<T, Ts>...>; }

static_assert(    contains<int,      bool, char, int, long>());
static_assert(    contains<bool,     bool, char, int, long>());
static_assert(    contains<long,     bool, char, int, long>());
static_assert(not contains<unsigned, bool, char, int, long>());
Run Code Online (Sandbox Code Playgroud)

现场演示


或者,适应了 struct

template<typename T, typename... Ts>
struct contains : std::disjunction<std::is_same<T, Ts>...>
{};
Run Code Online (Sandbox Code Playgroud)

或者,使用折叠表达式

template<typename T, typename... Ts>
struct contains : std::bool_constant<(std::is_same<T, Ts>{} || ...)>
{};
Run Code Online (Sandbox Code Playgroud)

现场演示

  • 由于我们在17领域有折叠表达式,我们不妨只写`is_same_v`. (3认同)
  • @qiubit`{}`*是* is_same`实例的直接列表初始化,换句话说,是构造它。[`is_same`](http://en.cppreference.com/w/cpp/types/is_same)具有一个隐式布尔转换操作符,该运算符继承自`integral_constant`,因此表达式产生布尔值。您也可以改写`std :: is_same &lt;T,Ts&gt; :: value`。 (2认同)