Home Dashboard Directory Help
Search

VC10 STL: emplace functions are not implemented for more than 1 parameter by Dávid Róbert


Status: 

Closed
 as Fixed Help for as Fixed


4
0
Sign in
to vote
Type: Bug
ID: 645116
Opened: 2/18/2011 6:38:14 AM
Access Restriction: Public
0
Workaround(s)
view
4
User(s) can reproduce this bug

Description

In Visual Studio 2010 (also in SP1 beta), the new emplace functions of containers are not implemented for more than one parameter.

I will use the std::vector<Val>::empace_back(..) function from now on, but all applies for all STL conatiners, and also other emplace-type member functions.

MSDN documentation (http://msdn.microsoft.com/en-us/library/dd647620.aspx) writes: Adds an element constructed in place to the end of the vector. Basically, this is something like what std::make_shared is doing, in the meanwhile it is doing some other magic (creating the shared_ptr in make_shared's case, reallocating the vector if necessary in emplace_back's case), it is calling the element type's constructor, forwarding its parameters.

According to MSDN, there is only one implementation of emplace_back, what is taking an rvalue reference of the contained type, and it will call the contained type's move-constructor (and reallocate, move the already contained elements before, if needed). But this means emplace_back is basically equivalent to push_back(Val&&), and this is what actually is in the <vector> header, emplace_back(Val&&) just calling push_back(Val&&).

There is also an undocumented(!) version of template<class T> emplace_back(T&&), implemented right after emplace_back(Val&&) in the <vector> header, and it is actually doing what the documentation is doing: after doing the necessary magic necessary for the vector to hold the extra element (reallocation, moving current elements around), it calls the element type's constructor, forwarding the parameter.

The problem is, that according to the standard, this is a variadic template function, there is no limit on the number of parameters, and VC10 compiler does not support variadic templates. "10 is not quite infinity", but in most cases, more than enough. So std::make_shared does a workaround for the lack of variadic template support, implementing it only for up to 10 parameters.

The workaround for the lack of multi-parameter emplace support involves creating a temporary object, passing it to emplace_back, then destroying the temporary, so there is an extra move constructor and destructor call in the process, making this a performance problem.
Details
Sign in to post a comment.
Posted by Microsoft on 6/13/2011 at 4:03 PM
Hi,

Thanks for reporting this bug - actually, partially implemented feature. We've fully implemented it, and this will be available in VC11. All containers will have emplace()/emplace_front()/emplace_back()/emplace_hint()/emplace_after() as specified by the Standard. Because we're generating many more "fake variadic" overloads, we've changed our scheme slightly. By default, up to 5 arguments will be supported, but this can be increased to 10 with a macro (at the cost of longer compile times and greater PCH memory consumption).

If you have any further questions, feel free to E-mail me at stl@microsoft.com .

Stephan T. Lavavej
Visual C++ Libraries Developer
Posted by Microsoft on 2/20/2011 at 11:17 PM
Thank you for submitting feedback on Visual Studio 2010 and .NET Framework. Your issue has been routed to the appropriate VS development team for review. We will contact you if we require any additional information.
Posted by Microsoft on 2/18/2011 at 6:59 AM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.