用类的第一个条目填充std::向量的首选方法
Prefered method of populating a std::vector of classes with its first entry
在审查一个大型软件项目时,我遇到了两种基本上相同的方法,即在std::vector 上推送初始条目
考虑像Foo 这样的类
class Foo
{
public:
Foo(int param){
m_param = param;
}
setParam(int param){
m_param = param;
}
private:
int m_param;
}
考虑到任何适用的指标,以下两者之间是否有一种首选方法。。。。速度、稳定性等
Foo bar;
int val = 5;
bar.setParam(val);
std::vector<Foo> fooVec(1, bar);
与
int val = 5;
std::vector<Foo> fooVec;
fooVec.push_back(Foo(val));
考虑到任何适用的指标,以下两者之间是否有一种首选方法。。。。速度、稳定性等
可以说
毫无疑问这是一种糟糕的风格:
auto test1()
{
Foo bar; // redundant default construction
int val = 5; // redundant load
bar.setParam(val); // only now setting the value
std::vector<Foo> fooVec(1, bar); // redundant copy
return fooVec;
}
这是一种很好的风格:
auto test2()
{
return std::vector<Foo>(1, Foo(5));
}
表现怎么样,我们都很关心,对吧?
但这在现实中意味着什么?一旦您启用了优化?。。。
__Z5test1v: ## @_Z5test1v
.cfi_startproc
## BB#0: ## %_ZNSt3__16vectorI3FooNS_9allocatorIS1_EEEC2EmRKS1_.exit1
pushq %rbx
Ltmp0:
.cfi_def_cfa_offset 16
Ltmp1:
.cfi_offset %rbx, -16
movq %rdi, %rbx
movq $0, 16(%rbx)
movq $0, 8(%rbx)
movq $0, (%rbx)
movl $4, %edi
callq __Znwm
movq %rax, (%rbx)
leaq 4(%rax), %rcx
movq %rcx, 16(%rbx)
movl $5, (%rax)
movq %rcx, 8(%rbx)
movq %rbx, %rax
popq %rbx
retq
.cfi_endproc
.globl __Z5test2v
.align 4, 0x90
__Z5test2v: ## @_Z5test2v
.cfi_startproc
## BB#0: ## %_ZNSt3__16vectorI3FooNS_9allocatorIS1_EEEC2EmRKS1_.exit1
pushq %rbx
Ltmp2:
.cfi_def_cfa_offset 16
Ltmp3:
.cfi_offset %rbx, -16
movq %rdi, %rbx
movq $0, 16(%rbx)
movq $0, 8(%rbx)
movq $0, (%rbx)
movl $4, %edi
callq __Znwm
movq %rax, (%rbx)
leaq 4(%rax), %rcx
movq %rcx, 16(%rbx)
movl $5, (%rax)
movq %rcx, 8(%rbx)
movq %rbx, %rax
popq %rbx
retq
.cfi_endproc
绝对没有任何区别。在这种情况下,生成的机器代码完全相同。
除非你有一个相当具体的理由使用其中一个,比如需要支持一个旧的(C++11之前的)编译器,否则我只会使用:
std::vector<Foo> fooVec { 5 }; // or fooVec { foo(5) };, if you really prefer
这几乎可以保证与其他任何一种一样快速、稳定等(可能会快一点,取决于…)
相关文章:
- C++从另一个类访问公共静态向量的正确方法是什么
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 声明高维向量的更简洁的方法
- 在C++中初始化向量映射的最有效方法
- C++11 迭代向量的新方法?
- std::find,返回所有找到的值的替代方法,而不仅仅是存在重复的向量的第一个值
- C++ STD 函数运算符:有没有一种方法可以通过函数将一个向量映射到另一个向量上?
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- 有什么方法可以将具有不同模板参数的模板类实例放入向量中?
- 当映射包含字符串向量作为值时,从值中获取键的有效方法
- 在向量中查找大于 0(或通常为 k)的最小元素的最佳方法是什么?
- 从数组中删除非唯一值、保持顺序和不使用向量的最佳方法?
- 使用192/256位整数求和无符号64位整数向量的点积的最快方法
- 访问类成员向量最后一项的正确方法
- 使用 std::vector::swap 方法在C++中交换两个不同的向量是否安全?
- 从列表/向量制作嵌套 for 循环的最佳方法是什么?
- 检查两个向量是否并行的最有效方法
- 如何从 node-ffi 调用 c++ 中以结构向量作为参数的方法?
- 返回向量元素的 l 值的正确方法是什么?
- 如何在方法主体中返回声明向量的引用?