3

我有以下代码:

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 nameto的转换,Employee以便操作员可以工作。
  3. 隐式调用 Employee(const string& s)object 上的构造函数string name
  4. 继续operator==

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

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

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

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

我犯了同样的错误。

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

谢谢!

4

2 回答 2

7

规则是:
临时对象只能绑定到const引用。

正如您提到的那样==,该类型
的对象需要转换为 type ,您的类中的转换运算符应该可以实现这一点。然而,创建的对象是一个临时对象。即一个没有名字的对象,它的寿命不够长,不需要一个名字。这样一个无名的临时对象不能绑定到一个非常量引用。[参考 1] 所以你需要的是一个 const 参考:namestd::stringEmployeeEmployeeEmployee

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

[参考 1]
规则的
动机:这个特定规则的动机由 Bajrne 在C++ 的设计和演变的第 3.7 节中概述。

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

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

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

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

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

于 2012-06-27T15:06:16.413 回答
0

*itr给你一个Employee,所以你正在比较Employee一个字符串,name

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

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

于 2012-06-27T15:02:37.380 回答