Consider the following code:
#include <vector>
struct S { int a; double b; };
int main()
{
std::vector<S> v;
v.push_back({3, 4.5});
}
g++ 4.4 complains that the call to push_back() is ambiguous:
error: call of overloaded ‘push_back(<brace-enclosed initializer list>)’ is ambiguous
note: candidates are: void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = S, _Alloc = std::allocator<S>]
note: void std::vector<_Tp, _Alloc>::push_back(_Tp&&) [with _Tp = S, _Alloc = std::allocator<S>]
Is this supposed to be ambiguous according to the Standard, or is this just an issue with g++?
I know it can be resolved by writing in the type of S explicitly:
v.push_back(S{3, 4.5});
but the type name of S may be long, so I'd rather not do that...
vector::push_back() push_back() function is used to push elements into a vector from the back. The new value is inserted into the vector at the end, after the current last element and the container size is increased by 1.
push_back(): Inserts a new element at the end of the vector. Its time complexity is O(1).
The difference in the efficiency of push_back and emplace_back depends on the type of our vector. If the vector is a built-in type, there is no difference between the efficiency of push_back and emplace_back. If the vector type is class or struct, emplace_back is more efficient than push_back.
The push_back() function is used to insert an element at the end of a vector. This function is available in the <vector> header file.
Does S
have to be a POD? If not, define a constructor, and it should work.
struct S
{
int a;
double b;
public:
S(int a, double b) : a(a), b(b) {}
};
Also, v.push_back({3, 4.5})
is probably less efficient than v.emplace_back(3, 4.5)
.
Update: Smells like a compiler bug. It works perfectly well with g++ 4.6.0 20101025 (experimental).
With the most recent draft (n3225), your code is in fact ambiguous. The candidates that are in vector will be
void push_back(const S& x);
void push_back(S&& x);
The question is: Is a list-initialization of a const S&
a better/worse conversion sequence than a list-initialization of a S&&
? Overload resolution will make both conversions user defined conversion sequences. This means they are not comparable because there is no rule that can do so.
This is handled by core issue #1079. If that issue gets accepted, the intention is that your code calls the second candidate. Incidentally, Jason Merril is a GCC developer :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With