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

时间:2012-06-27 14:57:16

标签: c++ operators implicit-conversion implicit

我有以下代码:

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 )应遵循以下步骤:

  1. 在课程operator==上认出它是Employee
  2. 尝试确定是否存在从string nameEmployee的转换,以便运营商可以正常工作。
  3. 隐式调用对象Employee(const string& s)上的构造函数string name
  4. 继续operator==
  5. 但是,这行在编译时给我带来了麻烦:

    Invalid operands to binary expression ('Employee' and 'string' (aka 'basic_string<char>'))
    

    即使我明确地调用构造函数:

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

    我得到了同样的错误。

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

    谢谢!

2 个答案:

答案 0 :(得分:7)

规则是:
Temporaries只能绑定到const引用。

正如您提到的==工作, 类型name的对象std::string需要转换为Employee类型,类Employee中的转换运算符才能实现此目的。但是,创建的Employee对象是一个临时对象。它是一个无名的对象,其长度不足以需要一个名称。这样一个无名的临时对象不能绑定到非const引用。 [参考1]
所以你需要的是一个const引用:

bool operator==(const Employee& e)
                ^^^^^^

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

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

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

void g()
{
    double ss = 1;
    incr(ss);    //note: double passed int expected
}
  

由于类型不同,int&无法引用传递的double,因此生成一个临时值来保存由ss值初始化的int。因此incr()修改了临时,结果没有反映回函数。

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

答案 1 :(得分:0)

*itr为您提供了Employee,因此您要将Employee与字符串name进行比较。

您需要的是if ( *itr.name == name )

这样您就可以将列表名称中的Employee与您要搜索的名称进行比较。