dot dot dot
dot dot dot

Reputation: 241

Implementing const range with template

I tried to use template to avoid code duplication in implementation of a const and non-const range over a std::vector.

The non-const version works, but the const version does not. I don't know why.

test.cpp. Compile with g++ test.cpp:

#include <vector>
#include <iostream>
enum Cv {
    constant,
    non_constant
};

template <typename T, typename Index, Cv Cv_enum>
class Vector_range_facade {
    typedef typename std::conditional <
            Cv_enum == Cv::constant,
                    const std::vector<T>, std::vector<T>
    >::type Vec;
public:
    typedef typename Vec::iterator Iterator;
    Vector_range_facade(Vec& vec, const Index start_id, const Index size)
            : vec_{vec},
              it_begin_{vec_.begin() + start_id},
              it_end_  {vec_.begin() + start_id + size}
    {}  
    Iterator& begin() {return it_begin_;}
    Iterator& end()   {return it_end_;}
private:
    Vec& vec_;
    Iterator it_begin_;
    Iterator it_end_;
};

int main()
{
    std::vector<int> a;
    a.resize(100);
    Vector_range_facade<int, int, Cv::constant> range(a,0,10);
    for (auto x : range) {
        std::cout << x <<"\n";
    }   
}

Upvotes: 1

Views: 50

Answers (1)

Vittorio Romeo
Vittorio Romeo

Reputation: 93304

std::vector::iterator always evaluates to the type of a non-const iterator, as it is a typedef defined inside std::vector which cannot know if it's being called on a const or non-const instance.

You need to conditionally select your iterator type, between std::vector::iterator and std::vector::const_iterator. Example:

typedef typename std::conditional <
        Cv_enum == Cv::constant,
        typename std::vector<T>::const_iterator, 
        typename std::vector<T>::iterator
>::type Iterator;

on wandbox

Upvotes: 3

Related Questions