2016-11-22 2 views
1

Ich habe eine Container-Klasse für einige eindeutige Zeiger auf Objekte.verschiebe eindeutige Zeiger zwischen deques

Ich muss jetzt eine von ihnen nehmen, etwas mit ihnen in einer anderen Klasse machen und an eine andere Klasse übergeben (und sie irgendwann recyceln und in den Container zurücklegen).

Unten ist der Umriss des Codes. Aber ich bin immer mit der richtigen Art und Weise zu verwechseln einzigartige Zeiger mit Funktionen zu bewegen:

using uptrPod = unique_ptr<Pod>; 
using dqUptrPods = deque<uptrPods>; 

class Container { 
public: 
    Container() : 
     n_elements_(500) 
    { 
     for (auto i = 0; i < n_elements_; i++) { 
     free_pods_.push_back(uptrPod(new Pod())); 
    } 

    const uptrPod&& getPod() { 
     auto up_pod= std::move(free_pods_[0]); 
     free_pods_.erase(free_pods_.begin()); 
     return up_pod; 
    } 

    void returnPod(const uptrPod&& up_pod) { 
     free_pods_.push_back(up_pod); 
    } 

private: 
    long n_elements_; 
    dqUptrPods free_pods_; 
}; 

class PodTracker { 

    void addPod(const uptrPod&& up_pod) { dq_pods_.pushback(up_pod); } 
    dqUptrPods dq_pods_; 
}; 

class PodHandler { 

    void movePod() { 
     up_pod = std::move(container_->getPod()); 

     /// do stuff with pod 

     pod_tracker_->addPod(up_pod); 
    } 

    Container* container_; 
    PodTracker* pod_tracker_; 
}; 

Ich erhalte die Fehlermeldung:

cannot bind std::unique_ptr l value to const uptrPod&& { aka const std::unique_ptr &&

Wie kann ich den Zeiger zwischen den Klassen Hand um?

Antwort

4

Pass/Rückgabe der std::unique_ptr Instanzen von Wert und explizit verwenden std::move:

uptrPod getPod() { 
    auto up_pod= std::move(free_pods_[0]); 
    free_pods_.erase(free_pods_.begin()); 
    return up_pod; 
} 

void returnPod(uptrPod up_pod) { 
    free_pods_.push_back(std::move(up_pod));   
} 

class PodTracker{ 
    void addPod(uptrPod up_pod) { dq_pods_.push_back(std::move(up_pod)); } 
    dqSptrPods dq_pods_; 
}; 

void movePod() { 

    // `std::move` is not necessary here, as `getPod()` 
    // is already a temporary (rvalue) 
    auto up_pod = container_->getPod(); 

    /// do stuff with pod 

    pod_tracker_->addPod(std::move(up_pod)) ; 
} 

example on wandbox


Beachten Sie, dass const rvalue Referenzen nicht viel Sinn machen - ein rvalue Referenz.

The main purpose of rvalue references is to allow us to move objects instead of copying them. And moving the state of an object implies modification. As a result, the canonical signatures for the move constructor and the move assignment operator both take its argument as a non-const rvalue reference.

(Von: "What are const rvalue references good for?")

+0

Es könnte sich lohnen, zu erklären, dass 'up_pod' ist noch ein L-Wert, unabhängig davon, ob es eine rvalue Referenz geben ist :) – TartanLlama

+1

, die perfekt zu funktionieren scheint ... Vielen Dank Vittorio – chrise

Verwandte Themen