11

C++ プログラムをコンパイルするのに問題があります。このエラーの助けをいただければ幸いです。ヘッダーファイルには、次のものがあります。

struct workerT{
 workerT() : status(true), threadSem(0){}
 bool status;
 std::function<void(void)> func;
 semaphore threadSem;
};

std::vector<workerT> workers;

私の .cc ファイルでは、次のようにベクターを初期化しようとしています。

fill(workers.begin(), workers.end(), workerT());

これは次のエラーで失敗します: error: 'TP::workerT& TP::workerT::operator=(const TP::workerT&)' is implicitly deleted because the default definition would be ill-formed: It points to the semaphore.h file . Semaphore.h は次のように定義されています。

 public:
  semaphore(int value = 0);
  ....

private:
  int value;
  ....
  semaphore(const semaphore& orig) = delete;
  const semaphore& operator=(const semaphore& rhs) const = delete;

「塗りつぶし」行を削除するとプログラムはコンパイルされますが、ベクトルを初期化したいので本当に必要です。ダミーの構造体を作成してベクターに push_back しようとすると、同じエラー メッセージが表示されます。

更新: ありがとう @DyP! コンパイルにはまだ助けが必要です。「塗りつぶし」行を次のように置き換えます。

std::generate(workers.begin(), workers.end(), free_func);

これをヘッダーに正確に追加しました:

workerT free_func(){
 return {};
}

これらのエラーの取得:

thread-pool.cc: コンストラクター 'ThreadPool::ThreadPool(size_t)': thread-pool.cc:33:58: エラー: タイプ 'ThreadPool::workerT (ThreadPool::)()' の引数が一致しません ' ThreadPool::workerT (ThreadPool::*)()' /usr/include/c++/4.6/algorithm:63:0 からインクルードされたファイル内、thread-pool.cc:15 から: /usr/include/c++/4.6/ bits/stl_algo.h: 関数 'void std::generate(_FIter, _FIter, _Generator) [ with _FIter = __gnu_cxx::__normal_iterator >, _Generator = ThreadPool::workerT (ThreadPool::*)()]': thread- pool.cc:33:58: ここからインスタンス化 /usr/include/c++/4.6/bits/stl_algo.h:5013:2: エラー: ' を使用する必要があります。'または '-> ' '__gen (...)' でメンバーへのポインタ関数を呼び出す場合、たとえば '(... ->* __gen) (...)' make: * [thread-pool.o ] エラー 1

更新--私の.ccファイルで:

 using namespace std;

 static workerT free_func(){
   return {};
 }

 ThreadPool(...args...){
   std::generate(workers.begin(), workers.end(), free_func);
 }

エラー:

thread-pool.cc:19:10: error: ‘workerT’ does not name a type
thread-pool.cc: In constructor ‘ThreadPool::ThreadPool(size_t)’:
thread-pool.cc:39:49: error: ‘free_func’ was not declared in this scope
make: *** [thread-pool.o] Error 1

再度更新します。

 static ThreadPool::workerT free_func(){
    return {};
 }

 ThreadPool(...args...){
   std::generate(workers.begin(), workers.end(), free_func);
 }

スレッドプール.h:

 struct workerT{
 workerT() : status(true), threadSem(0){}
 bool status;
 std::function<void(void)> func;
 semaphore threadSem;
};
4

1 に答える 1

6

0x499602d2 が正しく指摘しているように、fill3 番目の引数からコピー割り当てする必要があります。あなたの型は暗黙的にコピー不可であるため、使用できませんfill

ただし、generateベクトルを埋めるために使用できます。

#include <vector>
#include <algorithm>

struct noncopyable
{
    noncopyable() = default;

    // make it noncopyable
    noncopyable(noncopyable const&) = delete;
    noncopyable& operator=(noncopyable const&) = delete;

    // make it movable (thanks, gx_)
    noncopyable(noncopyable&&) = default;
    noncopyable& operator=(noncopyable&&) = default;
};

int main()
{
    std::vector<noncopyable> vec(10);
    std::generate(begin(vec), end(vec), []()->noncopyable{return {};});
}

注: これnoncopyableは、削除されていないアクセス可能なムーブ コンストラクターがある場合にのみ機能します。ただし、そのような ctor がない場合多くの vector を使用することはできません ( resizerequires MoveInsertable、copy-または move-ctor のいずれかが必要です)。


g++4.8 で を使用するgenerateには、無料の関数が必要です。バグだと思います。

#include <vector>
#include <algorithm>

struct noncopyable
{
    noncopyable() = default;
    noncopyable(noncopyable const&) = delete;
};

noncopyable free_func()
{  return {};  }

int main()
{
    std::vector<noncopyable> vec;
    std::generate(begin(vec), end(vec), free_func);
}

さらに別の質問は、そのようにベクトルを初期化できるかどうかです。いいえと思います。要素を構築fillするのでgenerateはなく、上書き (代入) します。つまり、それらを使用する前に、複数の要素を持つベクトルが既に必要です。

デフォルトで構築された N 個の要素でベクトルを初期化する最も簡単なバージョンは、コンストラクターを使用することです。

std::vector<noncopyable> vec(10);

vector10 個のデフォルトで構築された要素を持つ を作成します。唯一の要件は、noncopyableDefaultConstructible であることです (基本的に、デフォルトのコンストラクターが必要です)。


型がコピー不可かつ移動不可の場合、直接 (またはデータ メンバーとして) 使用してvector(*) 内に格納することはできません。Cコピー不可、移動不可の type を含むクラスを移動可能にするには、ポインターとしてX保存する必要があります。X

(*) できますが、ベクターのサイズ変更、挿入などはできません。

struct nocopies_nomoves
{
    nocopies_nomoves() = default;

    nocopies_nomoves(nocopies_nomoves const&) = delete;
    nocopies_nomoves& operator=(nocopies_nomoves const&) = delete;

    // not required to be explicitly deleted:
    nocopies_nomoves(nocopies_nomoves&&) = delete;
    nocopies_nomoves& operator=(nocopies_nomoves&&) = delete;
};

#include <utility>
#include <memory>
class C
{
public:
    C() : ptr( new nocopies_nomoves() ) {} // make_unique in C++1y

    // I don't think you need to explicitly define those as defaulted;
    // at least not if you don't declare ANY of the copy/move ctors, assignment ops
    // and dtor
    C(C&& rhs) = default;
    C& operator=(C&& rhs) = default;
    ~C() = default;

    // not required to be explicitly deleted:
    C(C const&) = delete;
    C& operator=(C const&) = delete;
private:
    std::unique_ptr<nocopies_nomoves> ptr;
};

これで、 を作成しvector<C>て使用できます (例: resizeinsert、 ...)

#include <vector>
#include <algorithm>

static C generate_C()
{
    return {};
}

int main()
{
    std::vector<C> vec(10);
    // note: futile statement below; overwrites the 10 default-constructed
    //       elements
    std::generate(begin(vec), end(vec), generate_C);
}
于 2013-11-09T21:13:12.433 に答える