Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why enums can't be used as arguments in this vector constructor?

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?

like image 300
Paul Jurczak Avatar asked Sep 18 '14 17:09

Paul Jurczak


People also ask

Can enum class have methods?

The enum class body can include methods and other fields. The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared.

Does R have enums?

R functions often have parameters with enumerated values. These are typically passed as a character vector and resolved using match. arg(). The Enum structure is very similar to that of a factor, except the data is character, not integer and with appropriate validation.


2 Answers

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) if InputIterator 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 type InputIterator 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);
like image 173
Marco A. Avatar answered Oct 05 '22 04:10

Marco A.


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.

like image 21
pmr Avatar answered Oct 05 '22 05:10

pmr