Why does the compiler not complain about
Because const counts another function signature. Your assumption that the function signatures are identical is incorrect.
A function marked as const will be called for any instance of const or a Type<T> link.
and how do you know which one is being called?
Put the cout statement in the function and check the following cases:
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(); }
The assignment operator will invoke the non-content version.
The const version looks better like
const T& value() const { std::cout << "const version" << std endl; return m_value; }
because you cannot always rely on RVO (return value optimization), and additional copies can be made (especially for older compiler implementations).
Also note that the assignment operator should return a reference to the current instance:
Type& operator=(const T& rhs) {value() = rhs; return *this;}
πάντα ῥεῖ
source share