转换是否允许使用std :: vector的模板构造函数获取迭代器?

Ale*_*nov 17 c++ stl vector

在C++ 11标准的第23.3.6.2节[vector.cons]中,如下所述:

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

9 效果:[first,last)使用指定的分配器构造一个等于范围的向量.
10 复杂性:使n只有调用T(其中,N是之间的距离的拷贝构造firstlast),并且没有重新分配,如果迭代的第一和最后被正向,双向或随机接入类别.它使命令N调用T的复制构造函数和命令log(N)重新分配,如果它们只是输入迭代器.

(此文本也存在于较旧的标准中).一方面,它不要求解除引用InputIterator应该导致存储在向量中的相同类型的值.另一方面,它讲述了使用复制构造函数,这种类型暗示了相同的类型.

我的问题是:如果可以在类型之间进行转换,那么使用这个构造函数的不同类型的元素序列是否有效?需要参考该标准.

例如,以下代码在ideone上运行正常.它是由标准保证,还是GCC恰好允许它?

#include <vector>
#include <iostream>

struct A {
    int n;
    A(int n_) : n(n_) {}
};

int main() {
    int arr[] = {1,2,3,4,5,6,7,8,9,10};
    std::vector<int> int_vec(arr, arr+10);
    std::vector<A> A_vec(int_vec.begin(), int_vec.end());

    for( std::vector<A>::iterator it=A_vec.begin(); it!=A_vec.end(); ++it )
        std::cout<< it->n <<" ";
    std::cout<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)

Moo*_*uck 11

来自C++ Jan 2012草案:

§23.2.3/ 3 [sequence.reqmts] .... i和j表示满足输入迭代器要求的迭代器,并引用可隐式转换为value_type的元素,[i,j]表示有效范围....

X(i,j)
X a(i,j)
要求:T应该是来自*i的EmplaceConstructible到X. 对于vector,如果迭代器不满足前向迭代器要求(24.2.5),则T也应该是MoveInsertable到X.范围[i,j)中的每个迭代器都应该被解引用一次.
post:distance(begin(),end())== distance(i,j)构造一个等于[i,j]范围的序列容器

Coren引起了我的注意,你引用的部分:

§23.3.6.2/8[vector.cons] template <class InputIterator> vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
效果:使用指定的分配器构造一个等于[first,last]范围的向量.
复杂性:仅对N 的复制构造函数进行N次调用(其中N是第一个和最后一个之间的距离),如果迭代器的第一个和最后一个是前向,双向或随机访问类别,则不进行重新分配.它使命令N调用T的复制构造函数和命令log(N)重新分配,如果它们只是输入迭代器.

在矢量特定区域,技术上应覆盖第一部分.但是,我相信这个对复制构造函数的引用是错误的,并且是迂腐的,复制构造函数的提及在复杂性方面是最大的,因此对复制构造函数的调用(仅使用转换构造函数)似乎我有效.这不像我希望的那么清晰.

Xeo引起了我的注意, C++标准核心语言活动问题,修订版78有一个问题(535)是关于如何在标准中"许多关于复制构造的规定都被用来指代"复制构造函数".这显然是不好的措辞."应该检查标准中"复制构造函数"这一术语的每次使用,以确定它是否严格适用于复制构造函数或任何用于复制的构造函数.(类似的问题适用于"复制赋值运算符",它与赋值运算符函数模板具有相同的关系.)"因此,纠正这种不良措辞是在他们的待办事项列表中.