【发布时间】:2019-03-19 17:37:23
【问题描述】:
出于教育目的,我尝试创建一个std::integer_sequence 并将其元素总结为一个参数包。我希望这很简单,并在下面编写了代码。
第 1 步:创建一组 add() 操作以正确处理同质的、基于整数的参数包。使用add<0,1,2,3>()-call 进行测试并正常工作。
第 2 步:在这一步中,我想传递一个 std::integer_sequence 作为模板参数,对序列中的整数求和。我失败了,看注释掉的代码。
如何将std::integer_sequence 作为模板参数传递?
一个错误消息是没有函数模板的实例与调用匹配。为什么?我希望整数序列等价于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;
}
...后来,经过很多有用的cmets。我学到了很多东西,现在有以下工作代码:
#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;
}
【问题讨论】:
-
复制并粘贴错误消息。请,只需粘贴文本。写一个描述错误的句子比逐字粘贴对您来说更多,对我们帮助更少。
-
错误信息是本地化的,所以我添加了一个大部分读者都能理解的翻译。
标签: c++ visual-studio-2017 variadic-templates template-meta-programming