Dlaczego nie kompilator narzekać
Ponieważ const
liczy innego podpisu funkcji. Twoje założenie, że podpisy funkcji są identyczne jest nieprawidłowe.
Funkcja oznaczona const
zostanie wywołana dla dowolnej instancji const
lub odwołania do.
i jak się dowiedzieć, który z nich jest wywoływany?
Umieść cout
oświadczenie w funkcjach i przetestować następujące przypadki:
template <class T>
class Type {
public:
Type() {}
T& operator=(const T& rhs) {value() = rhs; return value();}
T& value() {
std::cout << "non const version" << std endl;
return m_value;
}
T value() const {
std::cout << "const version" << std endl;
return m_value;
}
private:
T m_value;
};
int main() {
Type<int> t;
t.value();
Type<int> rt = t;
rt.value();
Type<int>* pt = &t;
pt->value();
const Type<int> ct;
ct.value();
const Type<int>& crt = t;
crt.value();
const Type<int>* pct = &t;
pct->value();
}
Operator przypisania wezwie niepodlegania wersję const.
Wersja const powinien lepiej wyglądać
const T& value() const {
std::cout << "const version" << std endl;
return m_value;
}
ponieważ nie zawsze można polegać na RVO (optymalizacja wartości zwracanej) oraz dodatkowe kopie mogą być podjęte (szczególnie dla starszych implementacji kompilatora).
pamiętać, że operator przypisania powinien zwrócić odwołanie do bieżącej instancji również:
Type& operator=(const T& rhs) {value() = rhs; return *this;}
Nie ignoruj słów kluczowych podczas określania, czy dwa sygnatury funkcji są "identyczne"! –