2

Say I have a little structure with an int, double, and std:string.

I have a vector of these structures.

The efficient C solution would be to allocate the array, then loop through and set the field's values. Each value is only calculated once and is stored where its final resting place is.

In C++11 I can use emplace_back() to avoid creating a temporary structure on the stack then copying it into the vector memory, and deleting the temporary structure. But I'm providing a brace-enclosed initializer list to emplace_back() and compiler complains there's no matching function for call to emplace_back with a brace-enclosed initializer list.

So must I write a three-argument public constructor in this case? And if I did so would it be as efficient as the C version?

cigien
  • 57,834
  • 11
  • 73
  • 112
Swiss Frank
  • 1,985
  • 15
  • 33
  • 1
    Why `{}`? `emplace_back` takes a variadic number of arguments, so you can do `emplace_back(i, d, s);` Perhaps I'm misunderstanding the question. Can you show the code you have an issue with? – cigien Aug 24 '20 at 19:41
  • 2
    Do you mean an aggregate? (instead of POD) – Marc Glisse Aug 24 '20 at 19:44
  • 3
    Something containing a non-POD like `std::string` is not a POD either. – Ulrich Eckhardt Aug 24 '20 at 20:07
  • 2
    Like [this](https://godbolt.org/z/ab5q6E). It is C++17, but you can easily adapt it to C++11. Also, check [this](https://stackoverflow.com/questions/45345175/avoiding-extra-move-in-make-unique-make-shared-emplace-etc-for-structures-that-u) – C.M. Aug 24 '20 at 22:35

1 Answers1

1

Since you mention structure instead of class, and since you also mention C, I suspect you have not defined a constructor.

With emplace_back you still construct something; you do it in place, but you do it. So you need to provide the constructor.

#include <iostream>
#include <string>
#include <vector>

struct Foo {
    Foo(int i, double d, std::string s) : i(i), d(d), s(s) {};
    int i;
    double d;
    std::string s;
};

int main() {
    std::vector<Foo> v;
    v.emplace_back(1,2.5,"hello");
    std::cout << v[0].i << ' '
              << v[0].d << ' '
              << v[0].s << ' ';
}
Enlico
  • 23,259
  • 6
  • 48
  • 102