即使直接构造函数起作用,为什么emplace_back仍失败?

时间:2018-07-20 13:11:30

标签: c++

为什么我可以直接调用构造函数,但是当我在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
}

1 个答案:

答案 0 :(得分: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用于在原位置创建列表 的对象,而不是稍后将它们复制/移动到列表中。没有理由像emplace_back那样使用push_back。使用emplace_back的正确方法是向其发送对象构造函数的参数,而不是对象本身。

push_back仅将对象按引用(右值)移动,并且元素类型具有移动赋值运算符,即可将您的对象移动到列表/向量中。

For more reading about move/copy and push_back/emplace_back