2015-02-03 3 views
1

조건부 변수가 CopyConstructible, MoveConstructible, CopyAssignable, MoveAssignable이 아닙니다.conditional_variable 객체를 벡터에 삽입하는 방법은 무엇입니까?

우리는 당신이 vector<unique_ptr<conditional_variable>>를 사용하는 것이 좋습니다 것이 이러한 시나리오 아니 당신은 할 수 없습니다

+0

당신은'시도 할 수 벡터 > 하나를 시작하는'condition_variable'의'vector'을 필요로하는 이유' –

+1

내가 궁금하네요. 어떤 문제를 해결하려면? – Nawaz

+0

아마도'std :: vector :: emplace_back'이 트릭을합니까? – Julian

답변

1

, 진행하는 올바른 방법은 무엇이

vector<conditional_variable> cond; 

conditional_variable c1; 
conditional_variable c2; 
cond.push_back(c1); 
cond.push_back(c2); 

처럼 호출 할 수 있습니다. 그럼 당신은 새로운 conditional_variable를 할당하여 벡터에 추가 할 수 있습니다

당신은 크기 인수 복용 생성자를 사용하여 기본 구성 할 수 있지만 복사 할 수 없습니다 또는 이동 무언가의 벡터 만들 수 있습니다
+0

) 감사합니다, 그 것을 사용할 것입니다 – user1416065

3

:

std::vector<std::condition_variable> cv_vec(20); 

그러한 벡터는 성장할 수 없지만 pop_back() 또는 clear() (그러나 erase() 또는 resize()이 아님)으로 수축 될 수 있습니다.

또는 간접적 인 추가 수준으로 모든 문제를 해결할 수 있으므로 대신 std::unique_ptr<std::condition_variable>의 벡터를 사용할 수 있습니다.

지금, 왜 지구 사람에,

+0

답장을 보내 주셔서 감사합니다 TC. 그런 식으로 conditional_variable vector를 사용하고 싶지 않습니다. 질문은 기본적으로 복사없이 클래스를 사용하는 방법을 찾는 것이 었습니다. 벡터의 생성자 그래서 이런 종류의 시나리오에서는 std :: unique_ptr <> 방법을 사용합니다. – user1416065

0

당신은 벡터 보류 A_with_cv 개체를 가지고함으로써, std::vector<A_with_cv>std::condition_variable를 얻을 수 있습니다 ... 난 아무 생각이 없다, condition_variable 같은 원시적 동기화이 작업을 수행 할 것 std::condition_variable을 복사하지 않는 복사 구성 자 및 복사 할당 연산자가있는.

// compile with: c++ -std=c++14 -o go main.cpp -pthread 

#include <iostream> 
#include <vector> 
#include <condition_variable> 
#include <chrono> 
#include <mutex> 
#include <thread> 

class A { 
public: 
    A()     {} 
    A(int d) : data_{d} {} 

    int data()   const { return data_; } 
    void set_data(int d)  { data_ = d; } 
private: 
    int data_{0}; 
}; 

class A_with_cv : public A { 
public: 
    A_with_cv(int d = 0) : A{d} 
    {} 

    A_with_cv(const A_with_cv &a) : A{static_cast<const A&>(a)} // don't copy cv_ ! 
    {} 

    A_with_cv &operator=(const A_with_cv &other) 
    { 
     static_cast<A&>(*this) = static_cast<const A&>(other); // don't copy cv_ ! 
    } 

    std::condition_variable  &cv()  { return cv_; }; 
    const std::condition_variable &cv() const { return cv_; }; 
private: 
    std::condition_variable cv_; 
}; 


struct Printer { 
public: 
    Printer(std::vector<A_with_cv> &vec) { 
     initiate_print(vec); 
    } 

    void initiate_print(std::vector<A_with_cv> &vec) { 
     for (auto it = vec.begin(); it != vec.end();) { 
      auto &val_ref = *it; 

      ++it; // increment 
      if (it != vec.end()) { 
       auto &next_ref = *it; 
       th_vec_.push_back(std::thread(
               [&]() { 
                std::unique_lock<std::mutex> lk(mut_); 
                val_ref.cv().wait(lk); 
                std::cout << val_ref.data() << std::endl; 
                lk.unlock(); 
                next_ref.cv().notify_one(); // notify next 
               })); 
      } else { 
       th_vec_.push_back(std::thread(
               [&]() { 
                std::unique_lock<std::mutex> lk(mut_); 
                val_ref.cv().wait(lk); 
                std::cout << val_ref.data() << std::endl; 
               })); 
      } 
     } 
    } 

    void wait_for_thread_completion() { 
     for (auto &th : th_vec_) { 
      th.join(); 
     } 
    } 
private: 
    std::mutex mut_; 
    std::vector<std::thread> th_vec_; 
}; 


int main() 
{ 
    std::vector<A_with_cv> vec; 
    vec.push_back(A_with_cv(1)); 
    vec.push_back(A_with_cv(2)); 
    vec.push_back(A_with_cv(3)); 

    Printer printer(vec); 

    std::this_thread::sleep_for(std::chrono::milliseconds{500}); 
    vec[0].cv().notify_one(); 

    printer.wait_for_thread_completion(); 
} 

그러나 이것에 대한 벡터를 사용할 때 매우주의 :

다음은 예입니다. 벡터는 요소를 재 할당 할 수 있으며 실제로는 더 이상 존재하지 않지만 condition_variable에 알리고 있다고 생각할 수 있습니다 (예를 들어, 특정 시간에 push_back을 수행하고 벡터 요소에 대한 반복기 및 참조가 있었기 때문에) 무효화 됨)! 따라서, std::list과 같은 요소를 재 할당/무효화하지 않는 컨테이너를 선호합니다 (또는 - 앞이나 뒤에있는 요소 만 추가한다고 가정하면 : std::deque) 등 안전합니다.

컨테이너를 사용할 때 요소를 재 할당/유효화하지 않으면 emplace를 사용해야합니다. 예 :

#include <condition_variable> 
#include <map> 
#include <list> 
#include <vector> 
#include <deque> 

int main() 
{ 
    std::deque<std::condition_variable> deq; 
    //deq.push_back(std::condition_variable());     // does not work 
    deq.emplace_back(); 

    std::list<std::condition_variable> li; 
    //li.push_back(std::condition_variable());     // does not work 
    li.emplace_back(); 

    std::map<int, std::condition_variable> ma; 
    //ma.insert(std::make_pair(1, std::condition_variable())); // does not work 
    //ma.emplace(std::make_pair(1, std::condition_variable())); // does not work 
    ma.emplace(std::piecewise_construct, 
       std::forward_as_tuple(1), 
       std::forward_as_tuple()); 

    return 0; 
} 
관련 문제