【发布时间】:2014-08-31 18:12:54
【问题描述】:
在回复 CodeReview 上的this question 时,我正在考虑如何编写一个模板函数来指示包含对象的const-ness。
具体来说,考虑这个模板化函数
#include <iostream>
#include <numeric>
#include <vector>
template <class It>
typename std::iterator_traits<It>::value_type average(It begin, It end) {
typedef typename std::iterator_traits<It>::value_type real;
real sum = real();
unsigned count = 0;
for ( ; begin != end; ++begin, ++count)
sum += *begin;
return sum/count;
}
int main()
{
std::vector<double> v(1000);
std::iota(v.begin(), v.end(), 42);
double avg = average(v.cbegin(), v.cend());
std::cout << "avg = " << avg << '\n';
}
它需要一个迭代器并根据包含的数字计算平均值,但保证不会通过传递的迭代器修改向量。如何将这一点传达给模板的用户?
注意,这样声明它:
template <class It>
typename std::iterator_traits<It>::value_type average(const It begin,
const It end)
不起作用,因为它不是迭代器,而是迭代器指向的东西,即const。我是否必须等待concepts 标准化?
请注意,我不想要求 const 迭代器,而是表明它们可以 在这里安全使用。也就是说,我不想限制调用者,而是想传达我的代码正在做出的承诺:“我不会修改你的基础数据。”
【问题讨论】:
-
你的
average函数应该接受常量和非常量迭代器。所以你不能 require 常量迭代器(某些迭代器类型可能没有对应的常量迭代器)。但是,您可以将迭代器包装到不允许修改的包装器中。 -
此外,由于
iterator_traits不提供相应的常量迭代器类型,因此无法从需要非常量迭代器的函数中调用受限的average函数。 -
@dyp:代码已经确实接受 const 或非 const 迭代器。问题是如何传达这个事实。
标签: c++ templates c++11 c++-concepts