从operator ==隐式调用构造函数

Mat*_*tan 3 c++ operators implicit implicit-conversion

我有以下代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

据我了解,有问题的行if ( *itr == name )应遵循以下步骤:

  1. 认识到它是operator==在课堂上Employee.
  2. 试图弄清楚是否有转换string name,Employee以便运营商可以工作.
  3. 隐式调用Employee(const string& s)对象上的构造 函数string name.
  4. 继续operator==.

但是,这行在编译时给了我麻烦:

Invalid operands to binary expression ('Employee' and 'string' (aka 'basic_string<char>'))
Run Code Online (Sandbox Code Playgroud)

即使我显式调用构造函数:

if ( *itr == Employee::Employee(name) )

我犯了同样的错误.

这令人困惑.我很难理解隐式构造函数调用何时起作用(以及为什么即使我显式调用构造函数,代码也不起作用).

谢谢!

Alo*_*ave 7

规则是:
临时工具只能绑定到const参考.

至于你提到的==工作,
目的name就是类型的std::string需要被转换为类型Employee,在你的类转换运营商Employee应该做到这一点.但是,创建的Employee对象是一个临时对象.一个无名对象,其活动时间不够长,无需名称.这样一个无名的临时对象不能绑定到非const引用.[参考1]
所以你需要的是一个const参考:

bool operator==(const Employee& e)
                ^^^^^^
Run Code Online (Sandbox Code Playgroud)

[参考1]
规则的
动机: Bajrne在C++的设计和发展的第3.7节中概述了这一特定规则的动机.

但是,我犯了一个严重的错误,即允许非常量引用由非l值初始化.例如:

void incr(int &rr) {r++;}    

void g()
{
    double ss = 1;
    incr(ss);    //note: double passed int expected
}
Run Code Online (Sandbox Code Playgroud)

由于类型的不同,int&无法引用double传递,因此生成临时ss值以保存由值初始化的int .这样incr()修改了临时,结果没有反映回功能.

因此,很多次临时对象在函数调用中不知不觉地生成,其中它们是最不期望的,并且可能(错误地)假设它们的函数对正在传递的原始对象起作用,而函数在临时对象上运行.因此,很容易编写一个临时对象.假设一件事并做另一件事的代码.为避免这种容易误导的情况,规则已经到位.