Sequence containers need to have fill constructors and range constructors, i.e. these must both work, assuming MyContainer
models a sequence container whose value_type
is int
and size_type
is std::size_t
:
// (1) Constructs a MyContainer containing the number '42' 4 times.
MyContainer<int> c = MyContainer<int>(4, 42);
// (2) Constructs a MyContainer containing the elements in the range (array.begin(), array.end())
std::array<int, 4> array = {1, 2, 3, 4};
MyContainer<int> c2 = MyContainer<int>(array.begin(), array.end());
Trouble is, I'm not sure how to implement these two constructors. These signatures don't work:
template<typename T>
MyContainer<T>::MyContainer(const MyContainer::size_type n, const MyContainer::value_type& val);
template<typename T>
template<typename OtherIterator>
MyContainer<T>::MyContainer(OtherIterator i, OtherIterator j);
In this case, an instantiation like in example 1 above selects the range constructor instead of fill constructor, since 4
is an int, not a size_type
. It works if I pass in 4u
, but if I understand the requirements correctly, any positive integer should work.
If I template the fill constructor on the size type to allow other integers, the call is ambiguous when value_type
is the same as the integer type used.
I had a look at the Visual C++ implementation for std::vector
and they use some special magic to only enable the range constructor when the template argument is an iterator (_Is_iterator<_Iter>
). I can't find any way of implementing this with standard C++.
So my question is... how do I make it work?
Note: I am not using a C++11 compiler, and boost is not an option.