【问题标题】:Why is emplace_back failing even though the direct constructor works? [duplicate]即使直接构造函数有效,为什么 emplace_back 会失败? [复制]
【发布时间】:2018-07-20 13:11:29
【问题描述】:

为什么我可以直接调用构造函数,但是当我在emplace_back中使用完全相同的参数时,我得到一个错误“没有匹配的成员函数调用'emplace_back'”?为了得到错误,我需要将一个列表传递给构造函数。这里一定有一些非常简单的事情,但我在搜索中找不到它。

这是一个最小的例子。

class A {
public:
    A(std::list<double> c){
    }
};

void test(){
    A an_A = A({0.0});               //No error
    std::list<A> list_of_As;
    list_of_As.emplace_back({0.0});  //Error
}

【问题讨论】:

    标签: c++


    【解决方案1】:

    {} 的问题在于它有几种可以描述的类型。现在,当您不指定类型时,编译器需要推断您要发送的输入类型,而它无法做到这一点。为此,您必须指定{} 的类型。

    void test(){
        A an_A = A({0.0});
        std::list<A> list_of_As;
        list_of_As.emplace_back(list<double>{0.0});
    }
    

    其他选项:

    下一堂课:

    class A {
    public:
        A(list<double> c, int a){
        }
    };
    

    你可以使用:

    list_of_As.emplace_back(list<double>{0.0}, 1);
    //list_of_As.emplace_back(A({0.0}, 1)); <-- Avoid using this. Explanation is right after this section.
    list_of_As.emplace_back(initializer_list<double>{0.0}, 1);
    

    置顶与推送

    是否有充分的理由不使用 A({0.0}) 而不是 list{0.0} 来解决问题?

    是的。 emplace_back 用于就地创建列表的对象,而不是稍后将它们复制/移动到列表中。没有理由像 push_back 那样使用 emplace_back。使用emplace_back 的正确方法是向其发送对象构造函数的参数,而不是对象本身。

    push_back 会将您的对象移动到列表/向量中,前提是它仅通过引用(右值)移动并且元素类型具有移动赋值运算符。

    For more reading about move/copy and push_back/emplace_back

    【讨论】:

    • 虽然这段代码可以解决问题,但如果解释一下它的作用方式/原因,答案会好得多。请记住,您的答案不仅适用于提出问题的用户,还适用于所有其他找到该问题的人。
    • 你说得对,我加个解释。
    • 在编辑之前,这个答案刚刚使用:list_of_As.emplace_back(A({0.0}));这看起来很简单,并且有效(也在我的实际项目中)。编辑帮助我更好地理解为什么我尝试过的方法不起作用。但是有什么好的理由不用 A({0.0}) 而不是 list{0.0} 来解决问题吗?
    • @NathanReading 我添加了一个新部分来回答您的新问题。
    猜你喜欢
    • 2018-07-22
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多