`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."
我在使用 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."