Search code examples
c++templatesvectoroverload-resolution

c++ vector constructor instantiation conflicts


I'm trying to implement vector container refering to http://www.cplusplus.com/reference/vector/vector/vector/. There are two constructors causing some problems:

template <typename T>
vector (size_type n, const T& val);

template <typename T>
template <typename InputIterator>
vector (InputIterator first, InputIterator last);

When I use vector<int> vec(100, 1);. It seems that both template constructor make instantiations. So I got template <typename T> vector (size_type n, const T& val) with T=int and template <typename T> template <typename InputIterator> vector (InputIterator first, InputIterator last) with T=int, InputIterator=int.

How do I solve that?


Solution

  • Note that the standard (since C++11) requires that the overloaded constructor of std::vector taking iterator as parameter only participates in overload resolution when the arguments passed act as iterator.

    This overload only participates in overload resolution if InputIt satisfies InputIterator, to avoid ambiguity with the overload (2).

    You can use SFINAE with std::iterator_traits to accomplish it for your own implementation of vector. e.g.

    template <typename InputIterator, typename = typename std::iterator_traits<InputIterator>::value_type>
    vector (InputIterator first, InputIterator last) { ... }
    

    For the case of InputIterator = int, std::iterator_traits<int> doesn't contain any member types like value_type, then the overload will be ruled out of overload resolution.


    BTW: More precisely, the problem is not "both template constructor make instantiations"; I'm not sure what's the exact type of size_type in your implementation, if it's some type other that int, like std::size_t, then for vector<int> vec(100, 1); the 1st overload won't be selected because it requires to convert the 1st argument from int to std::size_t, then the 2nd overload will be selected because it could produce a perfect match instantiation with InputIterator = int. That's not the behavior we expect.