为什么在一个声明为“const std :: initializer_list& li”的类中不是initializer_list?

时间:2012-11-28 12:09:07

标签: c++ c++11

  

可能重复:
  initializer_list and move semantics

环境:Linux,g ++ - 4.7

我使用std :: vector和我自己的类来测试它。我发现当使用std :: initializer_list构造一个向量时,它实际上调用了自定义类的复制构造函数来创建一个临时对象。因此,我认为它真的很无效,我使用“const std :: initializer_list& li”来替换它。

为什么它在STL库中真的很常见?例如:

// This is in STL: stl_vector.h
vector(initializer_list<value_type> __l, const allocator_type & __a = allocator_type())
//...

实际上有什么东西在我的脑海里滑动了吗?

我的测试代码如下所示:

#include <iostream>
#include <vector>
#include <initializer_list>

class Test
{
public:
    Test(const Test & t) : v(t.v) {
        std::cout << "Copy Cons" << std::endl;
    }
    Test(Test && t) : v(std::move(t.v)) {
        std::cout << "MC" << std::endl;
    }
    Test(int val) : v(val) {}
private:
    int v;
};

int main()
{
    std::vector<Test> vv({Test(0), Test(1), Test(2)});

    return 0;
}//main

它是输出:

Copy Cons
Copy Cons
Copy Cons

1 个答案:

答案 0 :(得分:3)

如果仔细查看第一条评论中提供的链接,您将看到复制发生的原因:

  1. 当您定义initializer_list时,编译器会将该列表的内容填充到一块内存中。然后,initializer_list只包含两个指向该块内存开头和结尾的指针。
  2. 将列表复制到构造函数中时,只复制指针。
  3. 当向量分配了自己的内存时,它会将对象从列表的chunk'o'mem复制到自己的内存中。这就是你看到拷贝ctor的地方,而不是列表本身被复制的时候。
  4. 您可以看到名为initializer lis的语法元素,即花括号和逗号分隔值列表,作为编译器将该列表的内容放入只读内存块的指令。 std::initializer_list只不过是该块的一对迭代器。