Avraam Mavridis
Avraam Mavridis

Reputation: 8920

Passing parameter pack to emplace stl function cause compilation bug

According to the definition of emplace_back, void emplace_back (Args&&... args); is a variadic template function. So, I wrote the following:

#include <vector>

int main()
{
  std::vector<int> myvector2(10,0);
  myvector2.emplace_back(1,2,3,4,5,6);
}

The compiler complains:

g++ -std=c++0x stlstudy.cc
‘
Internal compiler error: Error reporting routines re-entered.
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.7/README.Bugs> for instructions.
Preprocessed source stored into /tmp/cc7q32tE.out file, please attach this to your bugreport.

And the OS alerts:

Sorry, Ubuntu 13.04 has experienced an internal error.

The /tmp/cc7q32tE.out filen is too long to post it here and maybe it will not help. Am I doing something wrong or is compilation bug? I don't get it.

After the comments and the bug report: jrok gives a very good explanation about why this happens. I used gcc 4.7, I reported the bug and I got the following response:

Jonathan W***** <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to work|                            |4.8.0

--- Comment #1 from Jonathan W***** <redi at gcc dot gnu.org> ---
Seems to be fixed for 4.8 already.

Upvotes: 5

Views: 957

Answers (1)

jrok
jrok

Reputation: 55395

Internal compiler error is not your fault. Compilers are supposed to give a meaningful diagnostic in case of ill-formed input, not just crash on you.

However, the number and types of arguments of emplace_back must match one of the constructors of vector's value type. You have a vector of ints, so you can pass at most one argument that either has a matching type or is implicitly convertible to value_type. (You could leave argument list empty - that would construct the object using default constructor).

std::vector<int> v;
v.emplace_back(1);   // ok
v.emplace_back(1.0); // ok
v.emplace_back(1, 2); // not ok, there's no constructor for `int` that takes two ints

The purpose of emplace_back isn't to push multiple elements in the same statement (I got an impression that this is what you expected it to do - I thought the same a while ago) but to construct an element in place, forwarding the arguments to the constructor and avoiding copies).

Gcc 4.8. does error out, although the error message isn't particulalry helpul.

Upvotes: 7

Related Questions