gpt4 book ai didi

c++ - 重载运算符=

转载 作者:太空宇宙 更新时间:2023-11-04 11:25:58 25 4
gpt4 key购买 nike

这可能是一个微不足道的问题,但我没有找到满意的答案,也无法真正弄清楚发生了什么。

假设您有以下代码:

#include <iostream>

class Foo
{
public:
void operator=(int)
{
std::cout << "calling Foo::operator=(int)" << std::endl;
}
};

int main()
{
Foo a, b;
a = 10; // it works, of course, no questions here
a = b; // why does this work?
}

因为我重载了operator=Foo , 我希望这条线 a = b里面main()吐出编译器错误(即 a.operator=(b) 不应编译,因为没有从 bint 的隐式转换,后者是 Foo::operator=(int) 的输入类型)。为什么赋值a = b默默地工作,到底是怎么回事?编译器是否生成“默认”operator=(const Foo&)即使在我重载的情况下?

最佳答案

是的,编译器正在生成一个默认的、普通的 Foo& operator=(const Foo&) .只有四种情况不会生成隐式复制赋值运算符:

  • 您明确告诉它不要这样做(例如 Foo& operator=(const Foo&) = delete)
  • 你自己宣布了一个Foo (或 Foo&const Foo& )
  • 你的类(class)有一个非平凡可分配的成员(例如 unique_ptr<T> )
  • 你的类有一个定义的移动赋值运算符或构造函数(感谢 Brian)

更新 以下是标准中的一些相关部分。

12.8.18:

If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defined as defaulted

好的,但是您确实声明了一个复制赋值运算符,对吗?还是你?复制赋值运算符是什么:

12.8.17:

A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&. 121 [ Note: An overloaded assignment operator must be declared to have only one parameter; see 13.5.3. — end note ] [ Note: More than one form of copy assignment operator may be declared for a class. — end note ] [ Note: If a class X only has a copy assignment operator with a parameter of type X&, an expression of type const X cannot be assigned to an object of type X

所以没有。您声明为 Foo::operator=(int) 的函数,虽然是赋值运算符,但不是复制赋值运算符。因此它不满足上一段中不隐式声明一个的条件。

所有其他条件在 12.8.23 中定义:

A defaulted copy/move assignment operator for class X is defined as deleted if X has:

  • 具有非平凡对应赋值运算符的变体成员,并且 X 是类 union 类,或者
  • const 非类类型(或其数组)的非静态数据成员,或
  • 引用类型的非静态数据成员,或者
  • 类类型 M(或其数组)的非静态数据成员,不能被复制/移动,因为应用于 M 的相应赋值运算符的重载决策 (13.3) 会导致歧义或者从默认赋值运算符中删除或无法访问的函数,或者
  • 由于重载决议(13.3)而无法复制/移动的直接或虚拟基类 B,如应用于 B 的相应赋值运算符,导致歧义或被删除的函数或无法从默认赋值运算符访问,或
  • 对于移动赋值运算符,非静态数据成员或直接基类的类型没有移动赋值运算符并且不可平凡复制,或任何直接或间接虚拟基类。

关于c++ - 重载运算符=,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26666406/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com