C++ type of dereferenced iterator -


i tried make function sums elements of std::vector:

template<typename iteratort> auto sum(iteratort first, iteratort last) -> decltype(*first) {     decltype(*first) sum = 0;     (; first != last; ++first)         sum += *first;      return sum; } 

and got error:

cannot convert 'int' 'int&'

then after research found this: std::iterator_traits<iteratort>::difference_type. changed code to:

template<typename iteratort> auto sum(iteratort first, iteratort last) -> typename std::iterator_traits<iteratort>::difference_type {     std::iterator_traits<iteratort>::difference_type sum = 0;     (; first != last; ++first)         sum += *first;      return sum; } 

and did work, not sure why , if it's solution or not. in conclusion have 2 questions:

1) why decltype(*first) returns int& , not int expected
2) typename before std::iterator_traits<iteratort>::difference_type , why sum function doesn't work if remove it

there 2 main problems:

  • the type of a dereferenced iterator reference, can const, , std::vector can different vector's item type.

  • when item type e.g. bool, don't want sum in bool type.

the following code 1 solution:

#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;     (; 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; } 

note don't have define own sum: there std::accumulate.


Comments