2016-08-05 8 views
2

Ich habe eine harte Zeit herausfinden, wie man eine non-const Referenz auf ein Element in einer std::vector von einer Const-Klasse-Methode zurückgibt. Ein einfaches Beispiel, was ich werde ist,Const-Methode liefert nicht-const Referenz auf Vektorelement

template<class T> 
class MyClass 
{ 
public: 
MyClass : myVec(3) 
{ 
} 

T& x() const 
{ 
    return *(myVec.data())[0] 
} 

std::vector<T> myVec; 
} 

Das Verhalten, das ich für gehe, ist, dass ich die Dinge in der Lage sein möchten, dass zu tun, wie die folgenden,

MyClass obj<double>; 
obj.x() = 3.3; 
assert(obj.x()==3.3) 

Eigen gibt die gleiche Art von Verhalten, aber ich konnte nicht herausfinden, wie man es zur Arbeit bringt.

+0

@jlack Es ist nicht klar, warum Sie versuchen, einen nicht konstanten Verweis auf ein konstantes Objekt zurückzugeben. –

+1

Warum ist 'x' const? Wenn Sie einen mutierenden Accessor haben, sollte es nicht const sein. – NathanOliver

+0

Es ist fraglich, ob die Elemente in einem Container konstant sein sollten, nur weil der Container ist. Wenn ich einen konstanten Container mit nicht konstanten Zeigern habe, ist das dann grundlegend anders? Sie könnten die Const-Ness nur für die Elemente anzeigen, die vorhanden sind, und nicht für deren Wert. – nate

Antwort

10

Sie könnten const_cast verwenden, und es wird die Arbeit hier tun, (nach der Verwendung gebucht). Aber Sie werden es in diesem Fall (und in den meisten Fällen) nicht brauchen.

Sie könnten (und sollten) hinzufügen nicht-const Mitgliedsfunktion Überladung für sie. Dann gibt const member function den Verweis auf const zurück, non-const member function gibt den Verweis auf non-const zurück. Der entsprechende wird über overload resolution aufgerufen.

const T& x() const 
{ 
    return myVec[0]; 
} 
T& x() 
{ 
    return myVec[0]; 
} 
2

Standardbibliothek Container erweitern die const-ness des Behälters auf die Werte selbst. Da Ihre Klasse in x() konstant ist, ist auch der Vektor. Sie können const_cast verwenden, um die const aus dem Element in Ihrem Accessor zu entfernen.

return const_cast <T&> (*(myVec.data())[0]); 

Im allgemeinen wird diese schlechte Praxis betrachtet wird, da const ist da, um Sie zu schützen. Das Umgehen dieser Schutzmaßnahmen kann dazu führen, dass der Code schwieriger zu verstehen ist.

Verwandte Themen