4

I have

using namespace std;   // for convenience in SO question only
vector<pair<array<int,3>, int>> foo;

and want to emplace_back an element with pair::first holding {i,j,k} and pair::second holding q. The only way I could get this compiling was with the rather clumsy

foo.emplace_back(piecewise_construct,
                 forward_as_tuple(i,j,k),
                 forward_as_tuple(q));

Is this efficient (i.e. is it guaranteed that the tuples will be optimised away)? Or is there another way that is guaranteed efficient?

(I tried

foo.emplace_back(std::initializer_list<int>{i,j,k}, q);

but to no avail with gcc 4.8.1). I know that I can avoid this problem by defining

struct element : std::pair<std::array<int,3>,int>
{
  element(int i, int j, int k, int q)
  { first={i,j,k}; second=q; }
};

vector<element> foo;
foo.emplace_back(i,j,k,q);

but I'd prefer to do without such extra code.

Walter
  • 44,150
  • 20
  • 113
  • 196
  • What is a `pair,int>` ? Maybe you can come up with a simple name, then create a simple type... use that type from there on? For anyone looking at your code `pair,int>` is not really helping describe what it is meant to represent, a bit more typing on your side to create a type will help all uses, including your's. – David Rodríguez - dribeas Jun 01 '15 at 08:27
  • Can't get it to compile on GCC 5.1 : `error: no matching function for call to 'std::array::array(int&, int&, int&)'`. What compiler are you using ? – Quentin Jun 01 '15 at 08:28
  • Quentin, that is because I actually didn't do what I said in the question, sorry. I didn't use `array`, but some other vector-like (in the physical meaning of 'vector') type. – Walter Jun 01 '15 at 08:36

1 Answers1

4

std::array<T, N> doesn't have any constructor taking a std::initializer_list<U> for any U, not even for U = T. Don't mistake the fact that it can be initialised from a braced-init-list for the presence of such a constructor.

Instead, actually create an array.

foo.emplace_back(std::array<int,3>{i,j,k}, q);

There are hardly any guarantees about efficiency, and this is not guaranteed to be more efficient than your tuple approach. In practice, it shouldn't make much of a difference, I expect implementations to optimise both forms of emplace_back to the same machine code. If you really care, and you doubt that, measure it.