2016-04-05 2 views
0

При рассмотрении большого программного проекта, я пришел крест два способа сделать по существу то же самое, выдвигая начальную запись на станде :: векторПредпочитаемого метод заселять зЬй :: вектора классов с первой записью

рассматривать класс как 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); 

Ver Сус

int val = 5; 
std::vector<Foo> fooVec; 
fooVec.push_back(Foo(val)); 
+0

Лучшим способом было бы следовать конвенции. Если первое вставленное значение является каким-то особенным, я бы выбрал конструктор. Если нет, то я бы выбрал push_back. – vu1p3n0x

ответ

-1

Если у вас нет достаточно веской причины, чтобы использовать один из них, как и необходимости поддерживать более старую (предварительно C-++ 11) компилятор, я бы просто использовать:

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

Это в значительной степени гарантировано как быстрая, стабильная и т. Д., Как и любая другая (и может быть чуть быстрее, в зависимости ...)

+2

Это открывает банку червей. Что такое 5? это размер вектора или аргумент конструктору? Я не могу сказать, не просматривая документы, и я не самый худший разработчик. – SergeyA

+0

@SergeyA: Я не могу согласиться. Если вы этого не знаете, значит, вы просто не знаете язык, и жалуетесь на это, как жалуется, что французские люди ошибаются, когда они используют «боль», чтобы означать «хлеб», а не «болит». –

+1

Это забавно, но смысл '{5}' зависит от определения 'Foo'. Если 'Foo' может быть сконструирован из' int', это создает вектор размера 1. В противном случае вектор размера 5. –

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 

Абсолютно никакой разницы. Сгенерированный машинный код в этом случае точно такой же.

+0

Но все же вы хотели бы сгенерировать тот же код в стиле, не так ли? –

+0

@MaximEgorushkin совершенно! –

+0

Спасибо за ответ ... Я бы хотел увидеть test3, который был объявлением вектора, а затем push_back. – dafew