std :: vector的模板构造函数接受迭代器是否允许转换? [英] Is conversion allowed with std::vector's template constructor taking iterators?

查看:108
本文介绍了std :: vector的模板构造函数接受迭代器是否允许转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++ 11标准的23.3.6.2节[vector.cons]中,说以下内容:

In the C++11 standard, Section 23.3.6.2 [vector.cons], the following is said:

   template <class InputIterator>
     vector(InputIterator first, InputIterator last,
            const Allocator& = Allocator());




9 效果:构造一个等于的向量

10 Complexity :只对指定的分配器使用 [first,last)范围。 T的副本构造函数(其中N是 first last 之间的距离),并且如果first和last迭代器为前向,双向或随机访问类别。如果它们只是输入迭代器,它将使N调用T的副本构造函数,并重新分配log(N)订单。

9 Effects: Constructs a vector equal to the range [first,last), using the specified allocator.
10 Complexity: Makes only N calls to the copy constructor of T (where N is the distance between first and last) and no reallocations if iterators first and last are of forward, bidirectional, or random access categories. It makes order N calls to the copy constructor of T and order log(N) reallocations if they are just input iterators.

(this文本也存在于较旧的标准中)。一方面,它不要求取消引用 InputIterator 的值应与向量中存储的类型相同。另一方面,它讲述了使用复制构造函数,即哪种隐含相同类型。

(this text exists in the older standard as well). On one hand, it does not require that dereferencing an InputIterator should result in a value of the same type that is stored in the vector. On the other hand, it tells about using copy constructors, which sort of implies the same type.

我的问题是:在此构造函数中使用一系列不同类型的元素,前提是可以在类型之间进行转换?

My question is: is it valid to use a sequence of elements of different type with this constructor, provided that conversion between types is possible? References to the standard are desirable.

例如,以下代码可以正常工作在ideone 。是由标准保证的,还是GCC恰好允许它?

For example, the following code works fine at ideone. Is it guaranteed by the standard, or does just GCC happen to allow it?

#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;
}


推荐答案

摘自C ++ 2012年1月草案:

From C++ Jan 2012 draft:


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

§ 23.2.3/3 [sequence.reqmts] ....i and j denote iterators satisfying input iterator requirements and refer to elements implicitly convertible to value_type, [i, j) denotes a valid range....

X( i,j)

X a(i,j)

要求:T必须是EmplaceConstructible可以从* i转换为X
。对于矢量,如果迭代器不满足向前的
迭代器要求(24.2.5),则T也应可移动到X中。
范围[i,j)中的每个迭代器应被精确地取消引用一次。 。

post :distance(begin(),end())== distance(i,j)构造一个等于范围[i, j)

X(i, j)
X a(i, j)
Requires: T shall be EmplaceConstructible into X from *i. For vector, if the iterator does not meet the forward iterator requirements (24.2.5), T shall also be MoveInsertable into X. Each iterator in the range [i,j) shall be dereferenced exactly once.
post: distance(begin(), end()) == distance(i, j) Constructs a sequence container equal to the range [i, j)

Coren 让我注意到您引用的部分:

Coren brought my attention that the section you quoted:


§23.3.6.2/8 [vector.cons] 模板< ; class InputIterator> vector(InputIterator首先,InputIterator最后,const Allocator& = Allocator());

效果:构造一个等于范围[first,最后一个),使用指定的分配器。

Complexity :仅对T的复制构造函数进行N次调用(其中N是第一个和第二个之间的距离)如果最后一个迭代器属于前向,双向或随机访问类别,则没有重新分配。如果它们只是输入迭代器,它将使N调用T的副本构造函数,并重新分配log(N)订单。

§ 23.3.6.2/8 [vector.cons] template <class InputIterator> vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
Effects: Constructs a vector equal to the range [first,last), using the specified allocator.
Complexity: Makes only N calls to the copy constructor of T (where N is the distance between first and last) and no reallocations if iterators first and last are of forward, bidirectional, or random access categories. It makes order N calls to the copy constructor of T and order log(N) reallocations if they are just input iterators.

特定于矢量的区域和技术上应该覆盖第一部分。但是,我认为对复制构造函数的引用是错误的,并且很容易理解,提及复制构造函数的最大程度是复杂性,因此0调用了复制构造函数(仅使用转换构造函数)似乎对我有效

is in the vector-specific area and technically should override the first section. However, I believe this reference to the copy constructor is in error, and to be pedantic, the mention of copy-constructors is in the complexity as a maximum, and thus 0 calls to the copy constructor (only using a conversion constructor) seems to me to be valid. This is less clear than I would wish.

Xeo 引起了我的注意。到 C ++标准核心语言有效问题,修订版78 出现问题( 535 )是关于标准中关于复制构造的许多规定中的措辞仅指复制构造函数。,这显然是措辞很差。应检查标准中术语复制构造函数的每种用法确定它是否严格适用于复制构造函数或用于复制的任何构造函数。 (类似的问题适用于复制赋值运算符,它们与赋值运算符功能模板具有相同的关系。)因此,纠正此不良措辞已列在他们的工作清单上。

Xeo brought my attention to the fact that C++ Standard Core Language Active Issues, Revision 78 has an issue (535) is about how in the standard "many of the stipulations about copy construction are phrased to refer only to "copy constructors."' and this is obviously poor wording. "each use of the term "copy constructor" in the Standard should be examined to determine if it applies strictly to copy constructors or to any constructor used for copying. (A similar issue applies to "copy assignment operators," which have the same relationship to assignment operator function templates.)" So, correcting this poor wording is on their to-do list.

这篇关于std :: vector的模板构造函数接受迭代器是否允许转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆