Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
190 views
in Technique[技术] by (71.8m points)

c++ - Is conversion allowed with std::vector's template constructor taking iterators?

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 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 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.

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;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

From C++ Jan 2012 draft:

§ 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)
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 brought my attention that the section you quoted:

§ 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.

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 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...