Implicit call of constructor from operator==
c++, implicit, implicit-conversion, operators
Solution
The rule is: Temporaries can be bound only to a `const` reference.
As you mentioned for the `==` to work, The object `name` which is of the type `std::string` needs to be converted to type `Employee`, the conversion operators in your class `Employee` should make this happen. However, the created `Employee` object is an temporary object.i.e a nameless object which doesn't live long enough to need a name.Such a nameless temporary object cannot be bound to a non-const reference.[Ref 1] So what you need is a const reference:
bool operator==(const Employee& e)
^^^^^^
[Ref 1] Motivation for the rule: Motivation for this particular rule is outline by Bajrne in Section 3.7 of The design and evolution of C++.
I made one serious mistake, though, by allowing a non-constant reference to be initialized by an an non l-value. For example:
void incr(int &rr) {r++;}
void g()
{
double ss = 1;
incr(ss); //note: double passed int expected
}
Because of the difference in the type the `int&` cannot refer to the `double` passed so a temporary was generated to hold an int initialized by `ss`'s value. Thus the `incr()` modified the temporary, and the result wasn't reflected back to the function.
Thus many a times temporary objects are generated unknowingly in function calls, where they are least expected and one might (wrongly)assume that their function works on the original object being passed, whereas the function operates on the temporary.Thus it's easy to write a code that assumes one thing and does another.So to avoid such easy to mislead situations the rule was put in place.
Problem
I have the following code: ``` class Employee { friend string FindAddr( list<Employee> lst,string name ); public: Employee(const string& s){ cout << "Employee CTOR" << endl;} bool operator==( Employee& e) { return e.name == name; } private: string name; string addr; }; string FindAddr( list<Employee> lst, string name ) { string result = ""; for( list<Employee>::iterator itr = lst.begin(); itr != lst.end(); itr++ ) { if ( *itr == name ) { // Problematic code return (*itr).addr; } } return result; } ``` As I understand, the problematic line `if ( *itr == name )` should follow these steps: - Recognizing it is `operator==` on class `Employee`. - Trying to figure out if there is a conversion from `string name` to `Employee` so that the operator could work. - Implicitly call the constructor `Employee(const string& s)` on object `string name`. - Continue with `operator==`. However, this line gives me trouble at compile time: ``` Invalid operands to binary expression ('Employee' and 'string' (aka 'basic_string<char>')) ``` Even if I explicitly call the constructor: `if ( *itr == Employee::Employee(name) )` I get the same error. This is confusing. I'm having trouble to understand when implicit constructor call works (and why the code doesn't work even if I explicitly call the constructor). Thanks!