This code fragment:
enum {N = 10, M = 100};
vector<int> v(N, M);
fails to compile with Visual Studio 2013, due to the following error:
error C2838: 'iterator_category' : illegal qualified name in member declaration
What's wrong with it?
This code fragment:
enum {N = 10, M = 100};
vector<int> v(N, M);
fails to compile with Visual Studio 2013, due to the following error:
error C2838: 'iterator_category' : illegal qualified name in member declaration
What's wrong with it?
It's a bug in both VS2012 and VS2013 since it's not conforming to the C++11 standard (with _HAS_CPP0X
defined as 1):
C++03 23.1.1 [lib.sequence.reqmts]/9 says:
For every sequence defined in this clause and in clause 21:
— the constructor
template <class InputIterator> X(InputIterator f, InputIterator l, const Allocator& a = Allocator())
shall have the same effect as:
X(static_cast<typename X::size_type>(f), static_cast<typename X::value_type>(l), a)
ifInputIterator
is an integral type.
but from C++11 23.2.3 [sequence.reqmts]/14:
For every sequence container defined in this Clause and in Clause 21:
— If the constructor
template <class InputIterator> X(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type())
is called with a typeInputIterator
that does not qualify as an input iterator, then the constructor shall not participate in overload resolution.
That constructor should not have been considered at all
More here: https://stackoverflow.com/a/12432482/1938163
As a workaround you could "help the overload resolution a bit", e.g.
std::vector<int> v(static_cast<std::vector<int>::size_type>(N), M);
Since C++11 the vector
constructor accepting two InputIterators
should be disabled if the two arguments aren't iterators. VS2013 fails to implement this correctly.
This is a Visual Studio 2013 bug, from the error being generated (see it live), this is just a small portion:
[...]
see reference to function template instantiation 'std::vector>::vector<,void>(_Iter,_Iter)' being compiled
[...]>
It is attempting to use the constructor that takes two input iterators. Which would be a bug, both gcc
and clang
are fine with this code.
We can that in C++11 that constructor should not be considered:
Constructs the container with the contents of the range [first, last). This constructor does not participate in overload resolution if InputIt does not satisfy InputIterator, to avoid ambiguity with the overload 2 (since C++11)
This agrees with the draft C++11 standard section 23.2.3
Sequence containers paragraph 14 which says:
If the constructor
template <class InputIterator> X(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type())
is called with a type InputIterator that does not qualify as an input iterator, then the constructor shall not participate in overload resolution.