此代码片段:
enum {N = 10, M = 100};
vector<int> v(N, M);
由于以下错误,无法使用Visual Studio 2013进行编译:
错误C2838:'iterator_category':成员声明中的非法限定名称
它出了什么问题?
答案 0 :(得分:12)
这是VS2012和VS2013中的一个错误,因为它不符合C ++ 11标准(_HAS_CPP0X
定义为1):
C ++ 03 23.1.1 [lib.sequence.reqmts] / 9说:
对于本节和第21节中定义的每个序列:
- 构造函数
template <class InputIterator> X(InputIterator f, InputIterator l, const Allocator& a = Allocator())
具有与以下相同的效果:
X(static_cast<typename X::size_type>(f), static_cast<typename X::value_type>(l), a)
如果InputIterator
是整数类型。
但是来自C ++ 11 23.2.3 [sequence.reqmts] / 14:
对于本条款和第21条中定义的每个序列容器:
- 如果使用类型
template <class InputIterator> X(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type())
调用构造函数InputIterator
则不会 有资格作为输入迭代器,然后构造函数不应参与重载决策。
根本不应该考虑构造函数
更多信息:https://stackoverflow.com/a/12432482/1938163
作为一种解决方法,您可以&#34; 稍微帮助解决重载&#34;,例如
std::vector<int> v(static_cast<std::vector<int>::size_type>(N), M);
答案 1 :(得分:10)
从C ++ 11开始,如果两个参数不是迭代器,则应禁用接受两个vector
的{{1}}构造函数。 VS2013无法正确实现此功能。
答案 2 :(得分:2)
这是一个Visual Studio 2013错误,来自生成的错误( see it live ),这只是一小部分:
[...]
参见函数模板实例化'std :: vector&gt; :: vector&lt;,void&gt;(_ Iter,_Iter)'正在编译
[...]&GT;
它试图使用带有两个输入迭代器的构造函数。哪个是错误,gcc
和clang
都可以使用此代码。
我们可以在C ++ 11中考虑that constructor不应该考虑:
使用范围[first,last]的内容构造容器。如果InputIt不满足InputIterator,则此构造函数不参与重载解析,以避免与重载2的歧义(自C ++ 11起)
这与C ++ 11标准部分草案23.2.3
序列容器段 14 一致,其中说:
如果构造函数
使用类型InputIterator调用template <class InputIterator> X(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type())
,该类型不符合输入迭代器,然后是构造函数 不得参与重载决议。