开发者

C++11 vector push_back ambiguous

开发者 https://www.devze.com 2023-01-27 03:25 出处:网络
Consider the following code: #include <vector> struct S { int a; double b; }; int main() { std::vector<S> v;

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 :)

0

精彩评论

暂无评论...
验证码 换一张
取 消