为什么initializer_list不在一个类中清除一个"const std::initializer_list & li"?
Why is not initializer_list in a class decleared a "const std::initializer_list & li"?
可能的重复项:
initializer_list和移动语义
环境: 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
如果您仔细查看第一条评论中提供的链接,您将看到为什么会发生复制:
- 定义initializer_list时,编译器会将该列表的内容填充到内存块中的某个位置。然后,initializer_list仅包含指向该内存块的开头和结尾的两个指针。
- 将列表复制到构造函数中时,仅复制指针。
- 当向量分配了自己的内存时,它会将您的对象从列表的 chunk'o'mem 复制到它自己的内存中。这是您看到复制 ctor 的地方,而不是复制列表本身时。
您可以看到名为初始值设定项 lis 的语法元素,即大括号和逗号分隔值列表,作为编译器将该列表的内容放入只读内存块的指令。std::initializer_list
只不过是该块的一对迭代器。
相关文章:
- std::list<std::shared_ptr>::擦除得到了一个SIGSEGV
- 一个 std::list 可以包含不同的 std::unique_ptr<T>吗?
- boost::instrusive::list 带有自动取消链接钩子:我可以使用列表中的值来确定列表是否只有一个元素
- 为什么 std::list::splice 不是一个免费函数?
- 如何在std::list中插入一个新结构
- 按值将 std::list 从一个函数传递到另一个函数
- 为什么std::list可以有一个T类型的分配器
- 有效地从 std::list 中删除最后一个元素
- 您将如何为 std::list<std::string> 创建一个类型映射,以在<String> List in C++ 中为 Java 在 SWIG 中创建?
- 如何编写一个C++函数,根据处理返回不同类型的std::list
- list pushback一个包含字符串类型核心的结构
- Visual C++只使用一个std::list实现std::unorderede_map
- 如何在 std::vector 中查找重复项<strings>并返回一个 std::list 它们按字母顺序排序,在该结果列表中没有重复项
- std::list是一个循环列表!!等等,什么
- 如何编写一个接受std::vector或std::list的函数
- 如何在删除一个元素(double for循环)后正确地指向std::list
- std::list中end()之后的下一个迭代器
- 从迭代器返回一个std::list元素的引用
- List的析构函数无法删除最后一个节点
- 常量时间std::list将大小调整为给定的最后一个元素