我正在制作函数Fold,它可以接受不同的类,例如Sum,它们指定所做操作的类型。
#include <iostream>
#include <vector>
#include <list>
template <typename T>
struct Sum {
public:
auto operator() (T init, std::list<int>::const_iterator first,
std::list<int>::const_iterator last) {
for (auto it = first; it != last; ++it) {
init += *it;
}
return init;
}
};
template <typename Iterat, typename T, typename Operator>
T Fold(Iterat first, Iterat last, T init, Operator func) {
return func(init, first, last);
}
int main() {
std::list<int> a{1, 2, 3, 6};
std::cout << Fold(a.cbegin(), a.cend(), 0, Sum()) << std::endl;
return 0;
}
然而,当我运行代码时,我得到了错误";没有用于推导"Sum"的模板参数的可行构造函数或推导指南;
错误可以通过两种方式处理:
- 如果我使用";int";而不是";模板T";课堂总结
- 如果我在main((中指定要使用的类型,如:
Fold(a.cbegin(), a.cend(), 0, Sum<int>())
有其他方法可以纠正这个错误吗?我展示的两个更高的解决方案都不适合我的任务
模板参数是从(函数(参数中推导出来的。由于Sum
没有参数,因此无法推导模板参数。这里对此进行了解释。
然而,并没有失去一切。Sum
作为一个类,不使用模板参数。只有operator()
方法可以。因此,您可以只将模板放在operator()
方法中,并将Sum
保留为非模板类。
例如:
struct Sum {
public:
template <typename T>
auto operator() (T init, std::list<int>::const_iterator first,
std::list<int>::const_iterator last) {
for (auto it = first; it != last; ++it) {
init += *it;
}
return init;
}
};
我还将对迭代器进行模板化,就像您对Fold所做的那样。完整的代码示例,以及一些附加的用法示例是:
#include <functional>
#include <iostream>
#include <list>
#include <vector>
struct Sum {
public:
template <typename T, typename Iterat>
auto operator() (T init, Iterat first, Iterat last) {
for (auto it = first; it != last; ++it) {
init += *it;
}
return init;
}
};
template <typename Iterat, typename T, typename Operator>
T Fold(Iterat first, Iterat last, T init, Operator func) {
return func(init, first, last);
}
int main() {
std::list<int> a{1, 2, 3, 6};
std::cout << Fold(a.cbegin(), a.cend(), 0, Sum()) << std::endl;
// init is a float. While the iterators return int.
std::cout << Fold(a.cbegin(), a.cend(), 0.5 , Sum()) << std::endl;
std::list<std::string> b{"1", "2", "3", "6"};
std::cout << Fold(b.cbegin(), b.cend(), std::string(""), Sum()) << std::endl;
return 0;
}