c++ - 从 operator== 隐式调用构造函数

标签 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. 识别它是类 Employee 上的 operator==
  2. 尝试确定是否存在从 string nameEmployee 的转换,以便运算符(operator)可以工作。
  3. 在对象 string name 上隐式调用构造函数 Employee(const string& s)
  4. 继续 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 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.

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

关于c++ - 从 operator== 隐式调用构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11229135/

相关文章:

c++ - 将带有自定义删除器的 unique_ptr 移动到 shared_ptr

c++ - 为什么 C++ 需要作用域解析运算符?

javascript - Javascript 数字比较运算符究竟如何处理字符串?

c - float常量隐式转换为int类型什么时候会溢出

c++ - 自定义 OpenGL 缓冲类不显示任何内容

c++ - 带有 OO 的模板导致 Unresolved external symbol 问题

c++ - 修复 C++ 中的宏重新定义

c# - 如何在数学对象等表达式中使用自定义类?

c++ - 隐式转换 C++

Java:将具有不同类型的参数传递给函数