c++ 使用具有基类成员的结构时发生emplace_back错误?

tjrkku2a  于 2023-05-20  发布在  其他
关注(0)|答案(1)|浏览(128)

在下面的示例中,我有一个基结构和派生结构,每个结构都有一个成员,还有一个派生类型的向量。当我尝试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失败?

brgchamk

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上使用它。

相关问题