Friday, 22 July 2016

c++ - emplace_back not working with std::vector



I am trying to do emplace_back into a std::vector>, but could not find the right syntax to do it.



#include
#include


int main()
{
std::vector> v;
std::map a {{1,2}};

v.push_back({{1,2}});

v.emplace_back({1,2}); // error
v.emplace_back({{1,2}}); // error
v.emplace_back(({1,2})); // error

}


push_back works here, but not emplace_back. How can I get emplace_back working?


Answer



One can achieve that using a helper function as follows:



 #include 
#include


void emplace_work_around(
std::vector>& v,
std::initializer_list> && item
)
{
v.emplace_back(std::forward>>(item));
}

int main()
{

std::vector> v;

emplace_work_around(v,{{1,2}});
}


The problem was when we write:



v.emplace_back({{1,2}});  // here {{1,2}} does not have a type.



the compiler is not able to deduce the type of the argument, and it can't decide which constructor to call.



The underlying idea is that when you write a function like



template
void f(T) {}


and use it like




f( {1,2,3,4} ); //error


you will get compiler error, as {1,2,3,4} does have a type.



But if you define your function as



template
void f(std::initializer_list) {}

f( {1,2,3,4} );


then it compiles perfectly.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...