Reputation: 3366
#include <iterator>
#include <forward_list>
#include <string>
#include <vector>
using namespace std;
template<typename C>
using Iterator_type = typename C::iterator;
template<typename Iter>
using Iterator_category = typename iterator_traits<Iter>::iterator_category;
template<typename Ran>
void sort_helper(Ran beg, Ran end, random_access_iterator_tag){
sort(beg,end);
}
template<typename For>
void sort_helper(For beg, For end, forward_iterator_tag){
vector<decltype(*beg)> vc{beg, end};
sort(vc.begin(),vc.end());
copy(vc.begin(),vc.end(),beg);
}
template<typename C>
void sort(C& c){
using Iter = Iterator_type<C>;
sort_helper(c.begin(),c.end(),Iterator_category<Iter>{});
}
void test(vector<string>& vs, forward_list<double>& lls){
sort(vs);
sort(lls);
}
I get a compile error -- forming pointer to reference type double&
Code from Bjarne Stroustrup -- the C++ programming language 5.4.2.1 iterator_traits
Upvotes: 0
Views: 68
Reputation: 48467
In the following statement:
vector<decltype(*beg)> vc{beg, end};
the decltype
specifier yields a reference type (either because it dereferences a pointer that results in an lvalue and itself is an expression, or, because operator*
from the For
class-type declares a reference type as its return type) that cannot be stored in a vector. Instead, you should leverage std::iterator_traits
once again to get the underlying type.
vector<typename iterator_traits<For>::value_type> vc{beg, end};
Upvotes: 1
Reputation: 92271
From Bjarne's errata list for the book:
pg 125: s/decltype(*beg)/Value_type<For>/ reparing the use of decltype would take more space than I have here.
vector<decltype(*beg)>
tries to create a vector<double&>
, which is not possible.
Upvotes: 2