是否可以在C 中具有模板的单参数总和
Is it possible to have a templated, single-parameter sum function in C++?
在python中,我们可以做到这一点:
int_list = [1, 2, 3, 4, 5]
print(sum(int_list)) # prints 15
float_tuple = (1.2, 3.4, 9.9)
print(sum(float_tuple)) # prints 14.5
sum
函数采用任何知道如何添加彼此并为0添加并产生总和的元素。
我想在C 11中发挥相同的功能。我知道存在accumulate
方法,但是我想要一个采用单个参数的函数。本质上,我想知道如何编译以下代码:
#include <string>
#include <iostream>
#include <vector>
#include <deque>
#include <list>
template<typename iterable>
auto sum(iterable iterable_) {
auto it = iterable_.begin();
auto end = iterable_.end();
if (it == end) {
return 0;
}
auto res = *(it++);
while (it != end) {
res += *it++;
}
return res;
}
int main() {
std::vector<int> int_vector = {0, 1, 2, 3, 4, 5};
std::cout << sum(int_vector) << 'n'; // prints 15
std::deque<int> int_deque = {4, 5, 7};
std::cout << sum(int_deque) << 'n'; // prints 16
std::list<float> float_list = {1.2, 3.4, 9.9};
std::cout << sum(float_list) << 'n'; // should print 14.5, but produces error.
}
此代码几乎有效。问题在于,auto
看到return 0;
的情况是在峰值为空的情况下,并且假设该函数必须返回int
。然后看到float
版本返回float
,并感到困惑。有什么方法可以告诉编译器,如果 return float(0)
看到 return
稍后返回float
?
是的,您可以至少适用于标准容器。
标准容器定义了一个名为value_type
的类型别名,用于该容器中存储的值类型。对于一个空容器,您可以返回此类型的值结构的对象:
template<typename iterable>
auto sum(iterable const &iterable_) {
auto it = iterable_.begin();
auto end = iterable_.end();
if (it == end) {
return typename iterable::value_type();
}
auto res = *(it++);
while (it != end) {
res += *it++;
}
return res;
}
这确实取决于包含的类型是默认构造的,但这可能不是一个主要问题(当然适用于诸如int
和float
之类的原始类型)。
如果您希望某些东西可以与任何 abor c 11范围(也就阵列以及具有免费begin
和end
的容器,我们只能添加一些使用declarations并包装std::accumulate
template <class Range>
auto sum(Range&& range) {
using std::begin;
using std::end;
using T = std::decay_t<decltype(*begin(range))>;
return std::accumulate(begin(range), end(range), T{});
}
如果您不想包装accumulate
,那么您也可以重新实现该循环以做同样的事情。
即使在非标准容器中也可以使用以下方法;只要某些东西以合理的方式实现begin()
和end()
。
#include <list>
#include <iostream>
#include <type_traits>
template<typename iterable>
auto sum(iterable && iterable_) {
auto it = iterable_.begin();
auto end = iterable_.end();
typedef typename std::remove_reference<decltype(*it)>::type value_type;
if (it == end) {
return value_type(0);
}
auto res = *(it++);
while (it != end) {
res += *it++;
}
return res;
}
int main() {
std::list<float> float_list = {1.2, 3.4, 9.9};
std::cout << sum(float_list) << 'n'; // works now.
}
相关文章:
- 模板参数推导失败,函数参数/参数不匹配
- 有人可以帮助我理解这些参数/参数吗?
- 为什么具有 2 个参数参数的构造函数接受复制对象作为 1 个参数参数?
- 当超出列时,clang格式强制每个参数/参数拥有自己的行?
- 常量和非常量函数作为模板参数参数
- 功能指针参数参数转换为const
- C 从参数参数包创建向量或列表
- C 中函数参数/参数的分辨率
- 操作员[]作为成员函数的正确模板参数/参数是什么?
- 为什么可以将其他类型变量用作C 中常量参考参数参数的参数
- 如何从Windows CMD运行可执行文件并将其传递给文件输入的参数参数和重定向
- 使用 {} 作为默认参数参数类型
- 将多个cmd.exe参数/参数传递给Shellexecute(ex)
- C 参数参数未更新
- 如何识别模板参数参数是否是模板内结构中另一个类的实例?C++
- 在不使用"new"的情况下实例化参数参数中的对象
- 由 pthread_create() 调用的函数的多个参数 - 参数是函数指针
- 模板模板参数参数名称用法
- 重新定义默认参数:参数 2
- 声明我的成员函数参数/参数