I came across a compilation error in which I was hoping the compiler would implicitly use a custom lvalue reference operator rather than an assignment operator.
I have generated a minimum reproducible example that shows the phenomenon. Could someone explain what is happening here and potentially ways to allow the implicit lvalue reference operator to be called?
If I uncomment the assignment operator deletion this fails to compile:
#include <iostream>
template <typename T>
struct wrapper
{
private:
T t;
public:
wrapper( T _t ) : t( _t ) {}
// wrapper<T> operator=( T ) = delete;
operator const T&() const { return t; }
operator T&() { return t; }
};
int main()
{
wrapper<int> w( 0 );
std::cout << w << std::endl;
w = 1;
std::cout << w << std::endl;
}
But even if operator= is commented, w = 1 is not calling either operator [const] T&. It is simply using the wrapper(T) constructor to make a wrapper out of 1, and then the implicitly defined operator= to assign that value to w. If you delete operator=, that's clearly not possible.
The operator T& is being used only by the cout line, because it is an operator that can convert a wrapper (for which you have not overloaded <<) to something that << can deal with, an int.
I guess you wanted w = 1; to implicitly behave as if it was static_cast<int&>(w) = 1;.
The one above, by itself, is an incomplete answer, as the whole point is probably why doesn't w = 1; behave like static_cast<int&>(w) = 1;? And the answer is that operator= is special, as suggested in the answer linked in a comment by Artyer. The relevant wording in the standard is here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With