【问题标题】:为什么我无法在以下 c++ 代码中使用 push_back() 函数?
【发布时间】:2022-01-21 17:39:12
【问题描述】:

我正在尝试为一个名为customer 的结构创建一个结构向量——稍后我将在其他函数中使用它。但是,当我使用push_back() 函数时,出现以下错误

在模板中:调用隐式删除的“客户”复制构造函数

谁能解释一下为什么我会收到这个错误?

这是与我的问题相关的部分代码:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

struct cartitem{
    //members of the struct
};

struct customer{
    string name;
    string arrival_time;
    float total_price = 0.0;
    vector<cartitem> cart;
    fstream mycart;
};

vector<customer> Customers;

static customer newCustomer(string cname, string arrtime){
    customer b;
    b.name = cname;
    b.arrival_time = arrtime;
    Customers.push_back(b);
    return b;
};

【问题讨论】:

  • Customers 不是静态的,但 newCustomer 是。这可能不是你想要的。
  • 真正的罪魁祸首是fstream 成员。流不可复制。
  • 您希望newCustomer 创建一个新客户,将其副本添加到Customers,然后返回您刚刚创建的客户吗?无论如何,fstream 是不可复制的。目前还不清楚你在用它做什么,所以很难说应该对customer 和/或newCustomer 进行哪些更改

标签: c++ struct stdvector


【解决方案1】:

当您调用push_back() 时,您正在推送b副本。但是,customer 有一个fstream 成员,它不支持复制(仅移动),因此编译器隐式删除了customer 的复制构造函数,这是push_back() 试图调用的。这就是你得到错误的原因。

【讨论】:

  • 注意:emplace_back(std::move(b)) 可以解决这个问题(需要&lt;utility&gt; 标头),但(通常)由于“窃取”而使源(在本例中为b)处于未定义状态它的资源,而不是复制它们。
  • @CruzJean "emplace_back(std::move(b)) 可以解决这个问题" - push_back(std::move(b))emplace({cname, arrtime}) 也是如此(可能需要添加构造函数)。 “但(通常)将源(在本例中为 b)置于未定义状态” - 错误。正确的移动必须使源处于定义明确但未指定的状态。这与处于 undefined 状态不同。如果正确实现了移动操作,那么设置一个局部变量然后将其移动到其他地方是完全可以的。
  • 感谢您的回答。除了将文件定义为该结构的成员之外,还有其他方法可以将文件“链接”到结构变量吗?
  • 我尝试了 push_back(std::move(b)),它解决了问题,但与其余代码配合得并不顺利。所以我正在考虑删除 fstream 成员,但我需要另一种方法将 mycart 文件链接到客户结构的对象
  • @RemyLebeau 我说的一般。没有什么可以阻止移动使某物处于未定义状态。它只需要保证析构函数不会爆炸。
【解决方案2】:

和 Remy 的帖子一样,push_back 复制了一份。

创建一个构造函数并尝试:

customer &newCustomer(const string &cname, const string &arrtime){
    return Customers.emplace_back(cname, arrtime); // requires C++17 or you can return Customers.back()
};

这里的例子应该很有用:https://en.cppreference.com/w/cpp/container/vector/emplace_back

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    相关资源
    最近更新 更多