c ++ 20 std::integral_constant?

fud*_*udo 16 c++ std

我刚刚进入元编程,正在 youtube 上观看 Cppcon 频道,看到了这个std::integral_constant,但找不到它的用途。

据我所知,这是一种将值与其类型一起“打包”的方法,它可以用

std::integral_constant<int, 42> i;
std::integral_constant<bool, true> b;
std::integral_constant<float, 3.14> f;
...
Run Code Online (Sandbox Code Playgroud)

并且这些实例中的每一个都可以像它们包含的值一样使用,即:可以传递、用于数学运算、比较等。

但是我不明白为什么我应该使用这些结构而不是实际包含的值,也不明白我是否可以在运行时实际访问值类型(即:intboolfloat)来处理它。

有人可以提供一个实际使用此功能的简单示例吗?一个解释它的用法与使用实际值的区别的例子?

dfr*_*fri 10

std::integral_constant主要用作编写元编程特征的实用程序类型,特别是通过使用 type和 value对类型进行编码。通过让自定义 trait 从std::integral_constant我们的特化中继承,我们可以通过静态成员常量轻松、惯用地访问存储的非类型模板参数value,以及例如通过成员 typedef 访问该常量的值类型value_type


例子

std::integral_constant 例如,可以用于为矩阵类型编写维度特征

using index_t = int;
template <index_t M, index_t N, typename S> struct mat {
  // matrix implementation
};
Run Code Online (Sandbox Code Playgroud)

作为

#include <type_traits>

// Default dimensionality 0.
template <class T, typename = void>
struct dimensionality : std::integral_constant<index_t, 0> {};

template <typename S>
struct dimensionality<S, std::enable_if_t<std::is_arithmetic_v<S>>>
    : std::integral_constant<index_t, 1> {};

template <index_t M, index_t N, typename S>
struct dimensionality<mat<M, N, S>> : std::integral_constant<index_t, M * N> {};

template <class T>
inline constexpr index_t dimensionality_v = dimensionality<T>::value;
Run Code Online (Sandbox Code Playgroud)

演示

然而,一个更常见的用例是使用两个帮助器 typedefstd::true_typestd::false_type常见情况 where Tis bool

Type        Definition
----        ----------
true_type   std::integral_constant<bool, true>
false_type  std::integral_constant<bool, false>
Run Code Online (Sandbox Code Playgroud)

例如作为

#include <type_traits>

struct Foo {};

template <typename T>
struct is_foo : public std::false_type {};

template<>
struct is_foo<Foo> : public std::true_type {};

template<typename T>
constexpr bool is_foo_v = is_foo<T>::value;

static_assert(is_foo_v<Foo>, "");
static_assert(!is_foo_v<int>, "");
Run Code Online (Sandbox Code Playgroud)