使用第一个条目填充类的std :: vector的首选方法

时间:2016-04-05 16:18:01

标签: c++ c++11 stdvector

在审查一个大型软件项目时,我提出了两种基本相同的方法,在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));

2 个答案:

答案 0 :(得分:2)

  

考虑到任何适用的指标......速度,稳定性等,是否存在以下优选方法

可以认为 毫无疑问这种风格很差:

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

绝对没有任何区别。在这种情况下,生成的机器代码完全相同。

答案 1 :(得分:-1)

除非你有一个相当具体的理由使用其中一个,比如需要支持旧的(pre-C ++ 11)编译器,我只是使用:

std::vector<Foo> fooVec { 5 }; // or fooVec { foo(5) };, if you really prefer

这几乎可以保证与其他任何一个一样快速,稳定等等(并且可能更快,取决于......)