Aufruf der Memberfunktion .begin()
von std::vector
und std::begin()
auf rvalues führen zu unterschiedlichen Ausgängen, wie der folgende Test zeigt:Mitglied Funktion .begin() und std :: begin()
vector<int> a{ 1, 2, 3 };
vector<int>::iterator it1 = move(a).begin(); // OK
vector<int>::const_iterator it2 = move(a).begin(); // OK
vector<int>::iterator it3 = begin(move(a)); // Error!
vector<int>::const_iterator it4 = begin(move(a)); // OK
Hier mein Verständnis ist: std::begin()
Aufrufe const&
Überlast (da es &&
Überlast fehlt), und daher ein const_iterator
Objekt zurückgeben. So kann der Rückgabewert zu const_iterator
zugewiesen werden, aber nicht iterator.
- Ist mein Verständnis richtig?
- Warum hat
std::begin()
keine Rvalue-Überlastung?
Nur eine Anmerkung, die ich move(a)
verwendet zu demonstrieren .begin()
und std::begin()
auf rvalues aufrufen. Natürlich kann es durch jedes rvalue-Objekt ersetzt werden, für das .begin()
und std::begin()
gut definiert sind.
Bearbeiten: Hier ist das reale Beispiel zeigt, wo ich dieses Problem festgestellt habe. Ich habe viel vereinfacht, nur um die Idee zu vermitteln, wo std::begin()
auf einem rvalue aufgerufen wird. Also, da row_matrix
eine Proxy-Klasse ist, sollte es kein Problem geben, begin
und end
auf Rvalues aufrufen, da das zugrunde liegende Objekt identisch ist.
class matrix_row;
class row_iterator;
class matrix {
public:
matrix_row row(int i);
// other members
};
class matrix_row { // <- proxy class representing a row of matrix
public:
row_iterator begin();
row_iterator end();
// other members
private:
int row_;
matrix& matrix_;
};
class row_iterator {
// defined everything needed to qualify as a valid iterator
};
matrix m(3,4);
for(auto x = m.row(1).begin(); x != m.row(1).end(); ++x) {
*x /=2; // OK
}
for(auto x = begin(m.row(1)); x != end(m.row(1)); ++x) {
*x /= 2; // Error
}
[Dass 'std :: begin()' akzeptiert einen Rvalue überhaupt ist wahrscheinlich eher ein Unfall als beabsichtigte Design.] (Http://StackOverflow.com/questions/33586029/what-is-the-purpose-) of-the-const-Überladungen-von-stdbegin-and-end) –
* "Warum hat' std :: begin() 'keine Rvalue-Überladung?" * Was würde das tun? Klingt mir nicht allzu nützlich. –
'begin' ist nicht besonders nützlich, wenn der zugrundeliegende Bereich nicht mehr existiert. Daher erscheint es nicht sinnvoll, eine Rvalue-Überladung zu haben. –