C++类型的去引用迭代器
C++ type of dereferenced iterator
我试图制作一个函数,对std::vector
:的所有元素求和
template<typename IteratorT>
auto sum(IteratorT first, IteratorT last) -> decltype(*first) {
decltype(*first) sum = 0;
for (; first != last; ++first)
sum += *first;
return sum;
}
我得到了这个错误:
无法从"int"转换为"int&"
然后经过一些研究,我发现了这个:std::iterator_traits<IteratorT>::difference_type
。将我的代码更改为:
template<typename IteratorT>
auto sum(IteratorT first, IteratorT last) -> typename std::iterator_traits<IteratorT>::difference_type {
std::iterator_traits<IteratorT>::difference_type sum = 0;
for (; first != last; ++first)
sum += *first;
return sum;
}
它确实起了作用,但我不知道为什么,也不知道这是否是一个好的解决方案。总之,我有两个问题:
1) 为什么decltype(*first)
返回int&
而不是我预期的int
2) std::iterator_traits<IteratorT>::difference_type
之前的typename
到底做了什么?如果我删除它,为什么sum
函数不起作用?
有两个主要问题:
-
去引用迭代器的类型是引用,它可以是
const
,对于std::vector
,它可以与向量的项类型非常不同。 -
当项目类型为例如
bool
时,您不希望在bool
类型中求和。
以下代码是一个解决方案:
#include <iterator> // std::iterator_traits
template< class Iter >
auto sum( Iter first, Iter last )
-> decltype( typename std::iterator_traits<Iter>::value_type() + 0 )
{
decltype( typename std::iterator_traits<Iter>::value_type() + 0 ) sum = 0;
for (; first != last; ++first)
sum += *first;
return sum;
}
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
#define ITEMS( x ) begin( x ), end( x )
auto main()
-> int
{
vector<double> const v1 = {3, 1, 4, 1, 5};
cout << sum( ITEMS(v1) ) << endl;
vector<bool> const v2 = {0, 1, 1, 0, 1};
cout << sum( ITEMS( v2) ) << endl;
}
请注意,您不必定义自己的sum
:有std::accumulate
。
decltype(*first)
返回一个引用,否则我们将无法编写类似的东西
*first = 7;
关于difference_type
,还不清楚你想做什么。需要单词typename
来告诉编译器所谓的依赖类型(通常情况下是::
之后的任何类型)是模板而不是值。
试试这个:
#include <type_traits>
template <
typename Iter,
typename Ret = typename std::decay<decltype(*std::declval<Iter>())>::type>
Ret f(Iter first, Iter last)
{
Ret sum {};
for (; first != last; ++first) { sum += *first; }
return sum;
}
您做了一件随机的事情,它是随机工作的。distance_type
与您的问题无关,它是一种表示测量两个迭代器之间距离的结果的类型。由于它通常是一个整数类型,所以您最终可以在算术中使用它。
最初的问题是由于这样一个事实,即取消引用迭代器会返回一个指向底层对象的(const)指针,这是需要的,这样像这样的代码
*it = 10;
将执行您希望它执行的操作(或编译const迭代器失败)。
并且typename
关键字是必需的,但这里已经有足够多的typename
用法重复了。
- 不明白迭代器,引用和指针失效,一个例子
- C 地图 - 自引用迭代器
- 如何在find_if谓词中引用迭代器
- 尝试取消引用迭代器的分段错误
- 如何通过引用迭代器的解引用使幂等性
- 双取消引用迭代器的返回类型
- 正在返回与对象相同的取消引用迭代器
- 取消引用迭代器会导致'can not convert'错误,而它似乎不应该
- 通过取消引用迭代器将Vector写入文件
- 为什么我不能取消引用迭代器?
- 为什么我需要取消引用迭代器
- STL集合的去引用迭代器
- 递增解引用迭代器
- c++在解引用迭代器时x++与x = x+ 1的区别
- 指针向量解引用迭代器时出现段错误
- 标准如何处理容器插入函数中的自引用迭代器?
- 作为boost::bind复合链的一部分的解引用迭代器
- 解引用迭代器(c++)
- C++类型的去引用迭代器
- std::for_each等效项,它不取消引用迭代器