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…
With the most recent draft (n3225), your code is in fact ambiguous. The candidates that are in vector will be
The question is: Is a list-initialization of a
const S&a better/worse conversion sequence than a list-initialization of aS&&? 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 🙂