在下面的示例中,我有一个基结构和派生结构,每个结构都有一个成员,还有一个派生类型的向量。当我尝试push_back到vector时,它会按预期工作。但是,在尝试使用emplace_back时,我得到了一个编译错误。
#include <vector>
struct Foo
{
int foo{};
};
struct Bar : public Foo
{
int bar{};
};
int main()
{
std::vector<Bar> barVec;
// Works
barVec.push_back({2, 3});
// Doesn't work
//barVec.emplace_back(2, 3);
return 0;
}
/usr/include/c++/11/bits/alloc_traits.h:518:28: error: no matching function for call to ‘construct_at(Bar*&, int, int)’
518 | std::construct_at(__p, std::forward<_Args>(__args)...);
...
/usr/include/c++/11/bits/stl_construct.h:96:17: error: could not convert ‘std::declval()’ from ‘int’ to ‘Foo’
96 | -> decltype(::new((void*)0) _Tp(std::declval<_Args>()...))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| int
但是,如果我将第一个参数 Package 为Foo
,它就可以工作。
// Works
barVec.emplace_back(Foo{2}, 3);
我有点明白发生了什么(关于std::allocator_traits::construct
如何工作的一些事情),但我对细节感到困惑。push_back和emplace_back构造对象的步骤是什么,为什么最初的emplace_back失败?
1条答案
按热度按时间brgchamk1#
带括号的聚合初始化不支持大括号省略。(§dcl.init)
Bar b1(2,3);
会失败。Bar b2(Foo(2),3)
、Bar b2(Foo{2},3)
、Bar b2({2},3)
* 将成功{2}
(as braced-init-list),所以你也不能在vector::emplace_back
上使用它。