【问题标题】:C++ - constructor is implicitly deleted because the default definition would be ill-formedC++ - 构造函数被隐式删除,因为默认定义格式不正确
【发布时间】:2016-04-02 10:14:26
【问题描述】:

当我编译 main.cpp 时,我遇到了这些错误:

prod_cons.hpp:26:8:注意:'pile_params::pile_params(const pile_params&)' 被隐式删除,因为默认定义格式不正确: 结构堆参数{

main.cpp

pile_params pile_analyse(url_racine);
pile_params pile_telechargement(url_racine);
vector_params vect_all_pages();
vector<thread> threads_analyse;
vector<thread> threads_telechargement;

for(int i=0; i<nb_th_get;i++){
    threads_telechargement[i] = thread(telecharger,pile_telechargement,pile_analyse,vect_all_pages);
}

for(int i=0; i<nb_th_analyse;i++){
    threads_telechargement[i] = thread(analyser,profondeur,pile_telechargement,pile_analyse,vect_all_pages);
}

prod_cons.hpp

struct pile_params{
    deque<string> deck;
    stack<string> pile;
    string url_racine;
    condition_variable_any plein;
    condition_variable_any vide;
    mutex mut;
    pile_params(string _url_racine) : 
    pile(deck), url_racine(_url_racine), plein(), vide(), mut(){}
};

struct vector_params{
    vector<page> vect;
    condition_variable_any plein;
    condition_variable_any vide;
    mutex mut;
    vector_params(void) : 
    vect(), plein(), vide(), mut(){}
};

即使查看其他有关错误的主题,我也无法解决这个问题。

【问题讨论】:

  • 我认为问题不在于互斥体
  • 你错了,艾莎。 std::mutex 是不可复制的。结果是包含一个的structclass 也是不可复制的,因此复制构造函数的格式不正确,无法为其生成。尝试同时删除 mutexcondition_variable 成员(两者都是不可复制的),您会发现问题消失了。

标签: c++ struct constructor compiler-errors g++


【解决方案1】:

针对新的答案/问题,这里有一个完整的最小示例,它演示了如何解决问题。

您可以复制/粘贴此代码并直接编译/运行。

#include <iostream>
#include <string>
#include <memory>
#include <mutex>
#include <thread>
#include <functional>
#include <future>
#include <deque>
#include <stack>
#include <vector>
#include <condition_variable>

struct pile_params{
    std::deque<std::string> deck;
    std::stack<std::string> pile;
    std::string url_racine;
    std::condition_variable_any plein;
    std::condition_variable_any vide;
    std::mutex mut;

    pile_params(std::string _url_racine) :
    pile(deck), url_racine(std::move(_url_racine)), plein(), vide(), mut(){}
};

struct page {};

struct vector_params{
    std::vector<page> vect;
    std::condition_variable_any plein;
    std::condition_variable_any vide;
    std::mutex mut;

    vector_params() :
    vect(), plein(), vide(), mut(){}
};

void telecharger(pile_params &a_telecharger, pile_params &a_analyser, vector_params &tlp)
{

}

int main()
{
    auto url_racine = "";

    pile_params pile_analyse(url_racine);
    pile_params pile_telechargement(url_racine);
    vector_params vect_all_pages;
    std::vector<std::thread> threads_analyse;
    std::vector<std::thread> threads_telechargement;

    auto nb_th_get = 100;

    for(int i=0; i<nb_th_get;i++){
        threads_telechargement.emplace_back(telecharger,
                                            std::ref(pile_telechargement),
                                            std::ref(pile_analyse),
                                            std::ref(vect_all_pages));
    }

    for (auto&t : threads_telechargement)
    {
        if (t.joinable())
            t.join();
    }

    return 0;
}

最后一件事,在头文件中使用using namespace 是错误的。它会污染包含该标头的每个 cpp 文件中的全局命名空间。在具有 3 个文件的项目中,这无关紧要。当项目发展壮大时,这将非常重要。

【讨论】:

    【解决方案2】:
    1. 构造一个pile_params:

    pile_params pile_analyse(url_racine);

    1. 调用复制构造函数。

    thread(..., pile_analyse, ...);

    ...但是我们不能调用复制构造函数,因为 pile_params 是不可复制的...因为std::mutex 是不可复制的(条件变量,IIRC 也是如此)。

    一种解决方法是通过引用传递参数:

    threads_telechargement[i] = thread(telecharger,
                                       pile_telechargement, 
                                       std::ref(pile_analyse),
                                       vect_all_pages);
    

    另一种方法是将shared_ptr&lt;&gt; 传递给参数。

    【讨论】:

      【解决方案3】:

      如果构造函数、复制构造函数和移动构造函数未在结构或类中定义,则隐式创建这些函数。

      在 main.cpp 文件中,调用复制构造函数,该函数隐式生成如下:

      struct pile_params
      {
          ...
          pile_params(pile_params& pile_params) = default;
      };
      

      那么在 Members have an one 也是不可复制的,因此复制构造函数格式不正确,无法为其生成。

      std::mutex 成员的复制构造函数是不可复制的,例如:

      mutex( const mutex& ) = delete;
      

      【讨论】:

        猜你喜欢
        • 2015-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-20
        • 1970-01-01
        • 2022-01-22
        • 1970-01-01
        • 2013-11-21
        相关资源
        最近更新 更多