【发布时间】:2018-03-23 20:57:41
【问题描述】:
我正在尝试在 VS 2017 中编译这段代码,它应该打印一个向量的总和。
#include <stdio.h>
#include <functional>
#include <vector>
#include <iostream>
template<typename F, typename T, typename K>
//int fold(F fun, T acc, K v) get the same error below
int fold(F fun, T acc, std::vector<K> v)
{
switch (v.empty())
{
case true: return acc;
case false: return fold(fun, fun(*v.begin(), acc), { ++v.begin(), v.end() });
}
}
int main()
{
std::vector<int> v = { 1, 2, 3, 4 };
std::cout << fold([](int a, int b) {return a + b; }, 0, v);
}
它会产生错误:
错误 C2783: 'int fold(F,T,std::vector
>)': 无法推导出 'K' 的模板参数
这里为什么不能将K 推导出为int 或std::vector<int>?如果我替换
template<typename F, typename T, typename K>
int fold(F fun, T acc, std::vector<K> v)
与
template<typename F, typename T>
int fold(F fun, T acc, std::vector<int> v)
然后编译成功。
【问题讨论】:
-
您没有返回
case false:中的任何内容。打开编译器警告,也许不要在布尔值上使用switch。if (v.empty()) return acc;更具可读性。 (或return v.empty() ? acc : fold(…) -
另外,我不是 C++ 专家,但这看起来每次都复制向量的其余部分?为什么不接受迭代器而不是向量,例如
std::fill?你会想要返回T而不是int。 -
@Ryan感谢您的建议。但我实际上返回 acc 以防万一。你能再解释一下吗?
-
@Ryan 我这里只是想模拟一个sml函数折叠所以没注意效率
-
为什么不直接使用
std::accumulate?它的作用与您的fold函数应该做的完全一样,但它适用于任何集合,并且不会制作一堆不必要的集合副本。
标签: c++ functional-programming