c++20 std::integral_constant?

20
我只对元编程感兴趣,正在观看Youtube上的Cppcon频道,并看到了这个std::integral_constant,但找不到它的用途。
据我所知,它是一种将值与其类型“打包”的方式,可以实例化。
std::integral_constant<int, 42> i;
std::integral_constant<bool, true> b;
std::integral_constant<float, 3.14> f;
...

每个实例可以像它们所包含的值一样使用,例如:可以传递、在数学运算中使用、比较等。

但是我不明白为什么应该使用这些结构体而不是实际包含的值,也不知道是否可以在运行时访问值类型(即 intboolfloat)以便进行操作。

有人可以提供一个实际使用这个特性的简单示例吗?一个解释其用法差异的例子,与使用实际值的区别?


1
区别在于 std::integral_constant<int, 42> 是一种类型,而 42 是一个值。在模板代码中处理类型比处理值要容易得多。此外,它还有 value_typetype,可以在需要时将其转换为编译时的常量值。 - super
2
它是在C++11中添加的,而不是20? - HolyBlackCat
1个回答

13

std::integral_constant主要用作实用类型,用于编写元编程特性,特别是通过将类型和值编码来实现。通过让自定义特性继承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
};

as

#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;

演示

然而,更常见的用例是在Tbool时使用两个辅助类型定义std::true_typestd::false_type

Type        Definition
----        ----------
true_type   std::integral_constant<bool, true>
false_type  std::integral_constant<bool, false>
例如,作为
#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>, "");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接