The question title may not be super clear, but hopefully the below explains what is my problem.
Let's say I have the following (simplified) class template:
template <typename T, typename Container = std::vector<T>>
class MyVector {
using iterator = typename Container::iterator;
Container data{};
public:
MyVector(initializer_list<T> l) : data(l) {}
iterator begin() { return data.begin(); }
};
If I create an object like MyVector<int> vec {1, 2, 3}; it works fine.
However, if I try to create an object like MyVector<int, std::vector<int>&> vec; (note the &), then in the iterator type definition I get the error:
Type 'std::vector<int> &' cannot be used prior to '::' because it has no members
I tried exploring std::remove_reference and changed the line to:
using iterator = typename std::remove_reference<Container>::type::iterator;
but this also doesn't work - the error I get in this case is:
No type named 'iterator' in 'std::remove_reference<std::vector<int>>'
What I would like to achieve is to have a type definition (for iterator) that works if Container is a std::vector<T> as well as a reference to std::vector<T> (or whatever Container type is used, e.g. std::array - which means I cannot simply use std::vector<T>::iterator in the typedef).
Is there any way to achieve this?
CodePudding user response:
The std::remove_reference will work here. Or you need std::remove_reference_t version of it
using iterator = std::remove_reference_t<Container>::iterator;
// ^^^^^^^^^^^^
That is mean, if you do not have access to the c 14, provide a type alias for this
template< class T >
using remove_reference_t = typename remove_reference<T>::type;
Also note that, in order to work with
MyVector<int, std::vector<int>&> vec(v);
// ^^^^^^^^ --> not an ini-list
class MyVector must have a constructor
MyVector(Container c) : data(c) {}
The std::initializer_list will not work with reference qualified container type.
