简体   繁体   中英

`push_back` vs. `emplace_back` sign warning

I noticed when using Apple's clang - release (703.0.31) - that pushing a [signed] int onto a std::vector<unsigned int> via the push_back method would raise a warning about implicit sign conversion. I was satisfied with this, given the warning flags, but surprised that replacing it with the emplace_back method did not produce a warning.

I tested this with godbolt , and clang 3.9.0 exhibits the same behaviour. gcc 6.2 does not produce a warning in either case.

Since an implicit sign conversion diagnostic is not (AFAIK) required behaviour, I would hesitate to call it a bug, but I am curious if I'm overlooking some edge case that explains (or complicates!) the exhibited behaviour.

It's like the difference between this:

signed a = 0;
unsigned b = a;

And this:

unsigned b = unsigned(a);

The latter is a typical way to stop such warnings from happening (the other way would be a cast).

It's exactly the same when you call emplace_back() - the entire point of this method is to construct a value_type (unsigned in your case) from the given value.

Similarly, if you have:

struct Foo { explicit Foo(int x) {} };

Then you can do this:

std::vector<Foo> v;
v.emplace_back(1);

But not this:

v.push_back(1);

In summary, the meaning of emplace_back() is not "push_back() but more efficient." Instead, it is "construct a value_type using these arguments, inside the container."

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