简体   繁体   中英

C++11 vector push_back ambiguous

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM