隐式构造函数转换仅适用于显式vector :: vector

Pot*_*ter 2 c++ constructor type-conversion

我喜欢将二维数组初始化为vector<vector<int> >(x,y).x传递给vector<vector<int> >构造函数,y并传递给vector<int>构造函数,x时间.虽然这似乎被C++ 03禁止,但因为构造函数是explicit,它总是有效,即使在Comeau上也是如此.我也可以这样打电话vector::assign.但是,出于某种原因,不是vector::push_back.

        vector< vector< int > > v( 20, 40 ); // OK: convert 40 to const T&
        v.assign( 30, 50 ); // OK
        v.push_back( 2 ); // error: no conversion, no matching function, etc.
Run Code Online (Sandbox Code Playgroud)

出于某种原因,前两个示例是否真的符合要求?为什么我可以转换4050,但不2


结语:请参阅http://gcc.gnu.org/onlinedocs/libstdc++/ext/lwg-defects.html#438,了解为什么大多数编译器都允许这样做,但标准正在转向另一种方式.

AnT*_*AnT 5

你对Comeau隐含地调用explicit构造函数的假设很可能是不正确的.这种行为确实被打破了,但问题是不同的.

我怀疑这是Comeau附带的标准库实现中的一个错误,而不是核心Comeau编译器本身(尽管在这种情况下线条模糊).

如果你构建一个类似于构造函数属性的快速虚拟类std::vector并尝试相同的东西,你会发现编译器正确地拒绝执行构造.

它接受你的代码的最可能的原因是众所周知的双参数构造函数的正式模糊性std::vector.它可以解释为(size, initial value)构造函数

explicit vector(size_type n, const T& value = T(),
                const Allocator& = Allocator());
Run Code Online (Sandbox Code Playgroud)

或者作为(begin, end)模板构造函数,后者接受两个迭代器

template <class InputIterator>
  vector(InputIterator first, InputIterator last,
         const Allocator& = Allocator());
Run Code Online (Sandbox Code Playgroud)

标准库规范明确指出,当两个整数值用作参数时,实现必须确保以某种方式选择形成的构造函数,即(size, initial value).怎么做 - 没关系.它可以在库级别完成,可以在核心编译器中进行硬编码.它可以以任何其他方式完成.

但是,为了响应( 20, 40 )参数,Comeau编译器似乎错误地选择并实例化后一个构造函数InputIterator = int.我不知道它如何设法编译构造函数的专用版本,因为整数值不能也不会作为迭代器.

如果你试试这个

vector< vector< int > > v( 20U, 40 ); 
Run Code Online (Sandbox Code Playgroud)

您将发现编译器现在报告错误(因为它不能再使用构造函数的双迭代器版本),并且explicit第一个构造函数阻止它转换40为a std::vector.

同样的事情发生在assign.这当然是Comeau实现的一个缺陷,但是,再一次,实验表明,很可能所需的行为应该在库级强制执行(核心编译器似乎工作正常),并且不知何故它完成得不正确.


在第二个想法,我看到我的解释中的主要想法是正确的,但细节是错误的.另外,我认为在Comeau中将其称为问题可能是错误的.Comeau可能就在这里.

标准在23.1.1/9中说

构造函数

template <class InputIterator>  
X(InputIterator f, InputIterator l, const Allocator& a = Allocator())  
Run Code Online (Sandbox Code Playgroud)

应具有与以下相同的效果:

X(static_cast<typename X::size_type>(f),  
  static_cast<typename X::value_type>(l),  
  a)  
Run Code Online (Sandbox Code Playgroud)

如果InputIterator是一个整数类型

我怀疑,如果按照字面意思解释上述内容,则允许编译器假定在static_cast那里隐含了显式 (好吧......),并且代码是合法的,出于同样的原因static_cast< std::vector<int> >(10)是合法的,尽管有相应的构造函数explicit.存在static_cast是使编译器可以使用explicit构造函数的原因.

如果Comeau编译器的行为是正确的(并且我怀疑它实际上是正确的,正如标准所要求的那样),我想知道这是否是委员会的意图,让这个漏洞开放,并允许实现工作explicit向量元素的构造函数可能存在限制.