Milo Lu
Milo Lu

Reputation: 3366

Errors occur during tag dispatch

#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

Answers (2)

Piotr Skotnicki
Piotr Skotnicki

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

Bo Persson
Bo Persson

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

Related Questions