首页 > 解决方案 > 在给定默认实例化的情况下,在 STL 容器中调用哪个构造函数?

问题描述

《STL 教程和参考指南,第二版》中,示例 6.8 中,作者David Musser给出了以下示例来演示,“在创建初始值的N个副本时,向量构造函数调用元素类型的复制构造函数”:

#include <iostream>
#include <vector>
class U {
    public:
        unsigned long        id;
        unsigned long        generation;
        static unsigned long total_copies;
        /************************************************************************/
        U() :
            id{0},
            generation{0}
        {
        }
        U(unsigned long n) :
            id{n},
            generation{0} 
        {
        }
        U(const U& src) :
            id{src.id},
            generation{src.generation+1} 
        {
            ++total_copies;
        }
        
        // EQUALITY
        bool operator==(const U& src) { return id == src.id; }
        bool operator!=(const U& src) { return id != src.id; }
        
        // ASSIGMENT
        U& operator=(const U& src) 
        {
            id = src.id;
            generation = src.generation + 1;
            ++total_copies;
        }
};

bool operator==(const U& u1, const U& u2) 
{
    return u1.id == u2.id;
}
bool operator!=(const U& u1, const U& u2) 
{
    return u1.id != u2.id;
}

unsigned long U::total_copies {0};

using std::cout;
using std::endl;

int main()
{
    vector<U> vector1, vector2(3);
    for (int i=0; i!=3; ++i)
        cout << "vector2[" << i << "].generation: "
             << vector2[i].generation << endl;
             
    cout << "Total copies: " << U::total_copies << endl;
    
    return 0;
}

据他说vector<U> vector2(3),应该:

  1. 调用U默认 CTOR
  2. 然后调用UCopy CTOR,使用 #1 的结果来填充向量 3x。

因此,他将结果打印如下:

vector2[0].generation: 1                                                                                                                
vector2[1].generation: 1                                                                                                                
vector2[2].generation: 1                                                                                                                
Total copies: 3  

但是,当我运行代码时,它显示默认 CTOR 称为 3x,因此generation == 0没有创建任何副本。我的结果:

vector2[0].generation: 0                                                                                                                
vector2[1].generation: 0                                                                                                                
vector2[2].generation: 0                                                                                                                
Total copies: 0 

我也试过这个,我传递U一个参数,每次都会调用副本 CTOR 这个编译器依赖吗?为什么会存在差异?在容器中初始化用户定义的对象时,我们应该意识到这一点吗?

标签: c++stl

解决方案


@chris 将我指向cppreference.comstd::vector的CTOR 页面。看来这本书的结果与我的不同的原因是,这本书写于 2001 年,称为以下 CTOR(直到 2011 年):

explicit vector( size_type count, 
                 const T& value = T(),
                 const Allocator& alloc = Allocator());

所以调用vector<U> vector2(3)会先调用默认的UCTOR,然后复制一个。根据文档,“使用具有值的元素的计数副本构造容器。” 但是,自 2011 年起,以下 CTOR 被称为:

explicit vector( size_type count );

根据那里的文档,“使用默认插入的计数 T 实例构造容器。不制作副本。”


推荐阅读