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...
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 :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.