`push_back` 与 `emplace_back` 标志警告

`push_back` vs. `emplace_back` sign warning

我在使用 Apple 的 clang - release (703.0.31) 时注意到 - 通过 push_back 方法将 [signed] int 推送到 std::vector<unsigned int> 会引发有关隐式符号转换的警告.考虑到警告标志,我对此感到满意,但令我惊讶的是用 emplace_back 方法替换它并没有产生警告。

我用 godbolt, and clang 3.9.0 exhibits the same behaviour. gcc 6.2 测试过这两种情况都没有产生警告。

由于隐式符号转换诊断不是(AFAIK)必需的行为,我会犹豫将其称为错误,但我很好奇我是否忽略了一些解释(或复杂化!)所表现行为的边缘情况.

好像这两者的区别:

signed a = 0;
unsigned b = a;

还有这个:

unsigned b = unsigned(a);

后者是阻止此类警告发生的典型方法(另一种方法是强制转换)。

当你调用 emplace_back() 时完全一样 - 这个方法的全部要点是 construct a value_type (在你的情况下是未签名的)给定的值。

同样,如果您有:

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

那么你可以这样做:

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

但不是这个:

v.push_back(1);

综上所述,emplace_back()的意思不是"push_back() but more efficient."而是"construct a value_type using these arguments, inside the container."