Trying to write a generic code to emplace a default constructed object into an std container and return an iterator to it.
with insert the solution is
template<typename C>
typename C::iterator insert(C& container)
{
return container.insert(container.end(), typename C::value_type());
}
But emplace has no such common interface so I had to specialize it for 2 container types. My best attempt (that did not compile) was:
template<typename C>
auto emplace(C& container)
-> decltype(container.emplace_back())
{
return container.emplace_back();
}
template<typename C>
auto emplace(C& container)
-> decltype(container.emplace().first)
{
return container.emplace().first;
}
This causes: error: void value not ignored as it ought to be
and I don't understand why my decltype was deduced as void.
Used gcc 4.8.5 with -std=c++11
Edit:
reproduced by
int main() { std::vector v; std::vector::iterator iv = emplace(v);
std::set<int> s;
std::set<int>::iterator is = emplace(s);
return 0;
}
Edit 2:
second attempt
template<typename C>
auto emplace(C& container)
-> decltype(container.emplace().first)
{
return container.emplace().first;
}
template<typename C>
auto emplace(C& container)
-> decltype(container.emplace(container.end()))
{
return container.emplace(container.end());
}
works for verctor, but set is ambiguous.