gpt4 book ai didi

c++ - 汇总 std::integer_sequence 中的元素

转载 作者:太空宇宙 更新时间:2023-11-04 15:56:50 25 4
gpt4 key购买 nike

出于教育目的,我尝试创建一个 std::integer_sequence并将其元素汇总为参数包。我希望这很简单,并在下面编写了代码。

第 1 步:创建一组 add() 操作以正确处理同类的、基于整数的参数包。使用 add<0,1,2,3>() 测试-打电话和工作。

第 2 步:在这一步中,我想传递一个 std::integer_sequence作为模板参数,对序列中的整数求和。我失败了,看注释掉的代码。

我怎样才能传递 std::integer_sequence作为模板参数?

一个错误消息是函数模板 total 的实例没有与调用匹配。为什么?我希望整数序列等同于 int参数包。

另一条错误消息说 Args模板参数是非常量。怎么可能呢?我希望这是后续错误,但我在实验中经常看到这种错误组合。

我使用的是 Microsoft VC++ 2017 编译器。

#include <iostream>
#include <utility>

template <typename T>
T add(T first) {
return first;
}

template <typename T, typename ... Args>
T add(T car, Args... cdr) {
return car + add(cdr...);
}

template <int ... Args>
int total() {
return add(Args...);
}


int main(int argc, char** argv)
{
using std::cout;
using std::endl;

int s1 =
total<0, 1, 2, 3>();
std::cout << "s1 = " << s1 << std::endl;

// The following does not compile:
#if 0
int s2 =
total<std::make_integer_sequence<int, 4>>();
std::cout << "s2 = " << s2 << std::endl;

static_assert(s1 == s2, "no match");
#endif

// This should work:
//
{
cout << typeid(std::make_integer_sequence<int, 4>()).name() << endl;;
cout << std::make_integer_sequence<int, 4>().size << endl;;
}

return 0;
}

... 后来,经过大量有用的评论。我学到了很多东西,现在有了以下工作代码:

#include <iostream>
#include <utility>

template <typename T>
constexpr T add(T first) {
return first;
}

template <typename T, typename ... Args>
constexpr T add(T car, Args... cdr) {
return car + add(cdr...);
}

template <int ... Args>
constexpr int total() {
return add(Args...);
}

template<int... Args>
constexpr int total(std::integer_sequence<int, Args...>) {
return total<Args...>();
}

int main(int argc, char** argv)
{
using std::cout;
using std::endl;

constexpr int s1 =
total<0, 1, 2, 3>();
std::cout << "s1 = " << s1 << std::endl;

// The following now compiles. Oh, happy day!
#if 1
constexpr int s2 =
total(std::make_integer_sequence<int, 4> {});

std::cout << "s2 = " << s2 << std::endl;

static_assert(s1 == s2, "no match");
#endif

// This should work:
//
{
cout << typeid(std::make_integer_sequence<int, 4>()).name() << endl;;
cout << std::make_integer_sequence<int, 4>().size << endl;;
}

return 0;
}

最佳答案

使用 fold expressions 会容易得多:

template<class T, T... Args>
constexpr T total(std::integer_sequence<T, Args...> = {}) {
return (Args + ...);
}

int main() {
int s2 =
total(std::make_integer_sequence<int, 4>{});
// Or calling directly
int s1 = total<int, 0, 1, 2, 3>();
}

请注意默认的 std::integer_sequence 参数,因此如果您传递一个整数序列,它将推导出 Args 参数。

如果您希望能够在模板中使用 std::integer_sequence 类型调用它,只需创建一个辅助函数即可:

template<class IntegerSequence>
constexpr auto total_of(IntegerSequence argument = {}) {
return total(argument); // Will deduce `T` and `Args`
}

total_of<std::make_integer_sequence<int, 4>>();

关于c++ - 汇总 std::integer_sequence 中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55246960/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com