我有以下代码:
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;
}
据我了解,有问题的行 if ( *itr == name )
应该遵循以下步骤:
- 识别它是类
Employee
上的operator==
。 - 尝试确定是否存在从
string name
到Employee
的转换,以便运算符(operator)可以工作。 - 在对象
string name
上隐式调用构造函数Employee(const string& s)
。 - 继续
operator==
。
但是,这一行在编译时给我带来了麻烦:
Invalid operands to binary expression ('Employee' and 'string' (aka 'basic_string<char>'))
即使我显式调用构造函数:
if ( *itr == Employee::Employee(name) )
我得到了同样的错误。
这令人困惑。我无法理解隐式构造函数调用何时起作用(以及为什么即使我显式调用构造函数代码也不起作用)。
谢谢!
最佳答案
规则是:
临时对象只能绑定(bind)到const
引用。
正如您提到的要使 ==
起作用,
std::string
类型的对象 name
需要转换为 Employee
类型,您的类 中的转换运算符Employee
应该做到这一点。然而,创建的 Employee
对象是一个临时对象。即一个无名对象,它的生命周期不够长,不需要一个名字。这样一个无名的临时对象不能绑定(bind)到非常量引用。< sup>[引用 1]
所以你需要的是一个常量引用:
bool operator==(const Employee& e)
^^^^^^
[引用 1]
规则的动机:
Bajrne 在 C++ 的设计和演化 的第 3.7 节中概述了此特定规则的动机。
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 thedouble
passed so a temporary was generated to hold an int initialized byss
's value. Thus theincr()
modified the temporary, and the result wasn't reflected back to the function.
因此很多时候临时对象是在函数调用中不知不觉地生成的,这是最不期望的,并且人们可能(错误地)假设它们的函数对正在传递的原始对象起作用,而函数对临时对象起作用。因此很容易编写假设一件事做另一件事的代码。因此,为了避免这种容易误导的情况,制定了规则。
关于c++ - 从 operator== 隐式调用构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11229135/