重载赋值运算符而不返回语句

Dar*_*rio 5 c++ assignment-operator

为什么允许赋值运算符返回void?为什么分配链在这种情况下起作用?看一下代码,我会非常清楚我在说什么.

码:

struct Foo
{
   std::string str;

   Foo(const std::string& _str)
   : str(_str)
   {
   }

   Foo& operator=(const Foo& _foo)
   {    
      str = _foo.str;
      //return *this; /* NO RETURN! */
   }
};

int main()
{
   Foo f1("1");
   Foo f2("2");
   Foo f3("3");
   f1 = f2 = f3 = Foo("4");

   std::cout << "f1: " << f1.str << std::endl;
   std::cout << "f2: " << f2.str << std::endl;
   std::cout << "f3: " << f3.str << std::endl;

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 为什么合法?(为什么要编译)
  2. 它为什么有效?

我读过很多地方"赋值运算符应返回*让你可以有任务链",这完全是有道理的,但后来为什么上面的工作?

试一试:
使用上面代码在线c ++工作区

And*_*owl 8

为什么合法?(为什么要编译)

合法,并在程序中注入未定义的行为.你的编译器至少应该警告你(如果你设置了足够高的警告级别,我相信它会这样做).

根据C++ 11标准的第6.6.3/2段:

流出函数末尾相当于没有值的返回; 这会导致值返回函数中的未定义行为.

唯一的例外是main()函数,允许缺少return语句.按照第3.6.1/5段:

返回语句main具有离开main函数(销毁具有自动存储持续时间的任何对象)并std::exit使用返回值作为参数进行调用的效果.如果控件到达结尾而main没有遇到return语句,则效果就是执行

return 0;
Run Code Online (Sandbox Code Playgroud)

最后:

它为什么有效?

未定义的行为意味着您的程序可能在某些机器上运行但在其他机器上运行; 或者它今天可以在所有机器上运行,但不能在明天运行; 或者它会导致你的程序有一些奇怪的,不可预测的结果; 包括(这是最糟糕的情况)似乎运行得非常好.