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

标签 c++ stl vector

在 C++11 标准的第 23.3.6.2 节 [vector.cons] 中,有以下规定:

   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.

(此文本也存在于旧标准中)。一方面,它不要求取消引用 InputIterator 应该产生与存储在 vector 中相同类型的值。另一方面,它讲述了如何使用复制构造函数,这意味着相同的类型。

我的问题是:如果可以进行类型之间的转换,则在此构造函数中使用不同类型的元素序列是否有效?最好引用该标准。

例如,以下代码可以正常工作 at 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;
}

最佳答案

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

§ 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引起我注意的是您引用的部分:

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

位于特定于 vector 的区域,技术上应该覆盖第一部分。然而,我相信对复制构造函数的引用是错误的,并且迂腐地说,复制构造函数的提及是在最大复杂性中,因此对复制构造函数的 0 次调用(仅使用转换构造函数)在我看来是有效的。这比我希望的要不清楚。

Xeo让我注意到 C++ Standard Core Language Active Issues, Revision 78有一个问题( 535 )是关于标准中如何“许多关于复制构造的规定都被表述为仅指“复制构造函数”。”这显然是糟糕的措辞。“每次使用术语“复制构造函数”应检查标准中的“”,以确定它是否严格适用于复制构造函数或用于复制的任何构造函数。 (类似的问题也适用于“复制赋值运算符”,它与赋值运算符函数模板具有相同的关系。)”因此,纠正这种糟糕的措辞是他们的待办事项列表。

关于c++ - 使用迭代器的 std::vector 模板构造函数是否允许转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59733212/

相关文章:

c++ - 通过默认字符串简化 vector 中字符串的初始化

c++ - 空类的大小

c++ - 给定一个 future 容器,如何以非阻塞方式执行所有获取?

C++ 第二个计数器

c++ - glDebugMessageCallback 导致段错误

c++ - 为什么这个 vector 迭代器不会失效?

c++ - 如何打印 C++ 中相互依赖的枚举值的名称

c++ - 将 vector 元素插入队列

c++ - 如何根据动态属性对项目进行排序?

c++ - munmap_chunk : Assertion `ret == 0' failed