为什么 std::max 由 const& 返回?

Agr*_*hak 5 c++ return reference constants max

我想找到最大值Foo并调用inc()它,这是一种非常量方法。当然,在寻找最大值时,我不想创建任何副本或移动,即我不想Foo foo = std::max(foo1, foo2). 我尝试编写自己的最大值,而 g++ 坚持我返回一个 const&。

#include <iostream>

class Foo
{
public:
  Foo(int x) : x_(x) { std::cout << "const" << std::endl; }
  Foo(const Foo& foo) : x_(foo.x_) { std::cout << "copy const" << std::endl; }
  Foo(Foo&& foo) : x_(foo.x_) { std::cout << "move const" << std::endl; }
  bool operator< (const Foo& foo) const { return x_ < foo.x_; }
  bool operator> (const Foo& foo) const { return x_ > foo.x_; }
  void inc() { ++x_; }
  int x_;
};

/*
 * Doesn't compile.  Must return const T& or must accept non-const T&
 *
template<typename T>
inline T& my_max(const T& f1, const T& f2)
{
  return f1 > f2 ? f1 : f2;
}
*
*/

int main()
{
  Foo foo1(6);      
  Foo foo2(7);      
  Foo& foo = std::max(foo1, foo2); //Doesn't compile.  Must be const Foo&. But then next line fails
  foo.inc();
  std::cout << foo.x_ << std::endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

ISa*_*ych 2

你这里有两个问题:

  1. 结果中缺少 const 限定符
  2. 返回对 const 引用参数的引用是危险的

在这种情况下:

Foo& foo = std::max(Foo(6), Foo(7));
Run Code Online (Sandbox Code Playgroud)

编译器将在函数调用之前为参数构造临时对象,并在函数调用之后销毁它们 - 因此您最终将引用垃圾。当然,如果您始终使用现有对象,它会起作用 - 但很容易忘记这些限制。

您可以从参数中删除 const ,这将解决这两个问题,并且它对您来说应该没问题,因为您无论如何都打算修改对象。