簡體   English   中英

為什么std :: max按const&返回?

[英]Why does std::max return by const&?

我想找到max Foo並在其上調用inc() ,這是一種非const方法。 當然在尋找最大值時,我不想創建任何副本或移動,即我不想要Foo foo = std::max(foo1, foo2) 我嘗試編寫自己的max,而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;
}

你有2個問題:

  1. 結果中缺少const限定符
  2. 返回對const引用參數的引用是危險的

在這種情況下:

Foo& foo = std::max(Foo(6), Foo(7));

編譯器將在函數調用之前為參數構造臨時對象,並在函數調用后將其銷毀 - 因此您最終會引用垃圾。 當然,如果你總是使用現有的對象它會起作用 - 但很容易忘記這些限制。

您可以從參數中刪除const,這將解決這兩個問題,因為您打算修改對象,它應該沒問題。

template<typename T>
T my_max(T&& f1, T&& f2) {
  return std::forward<T>(f1 > f2 ? f1 : f2);
}

以上是相對堅實的,並將做你需要的。 它確實需要兩個參數具有相同的r / l / const ness,而std::max則沒有。 這就是為什么max使用const&

可以編寫一個更復雜的版本來查找公共引用類別,但它可以以令人驚訝的方式運行。

所以不要被上面缺少&返回值所迷惑:在你的用例中,上面返回一個引用。 如果傳遞rvalues,則返回一個值。

這是對super_max的嘗試,如果傳遞相同類型的左值,則返回左值。 如果傳遞兩種不同的類型或rvalue,則返回一個副本:

template<class A, class B>
struct max_return:std::common_type<A,B>{};
template<class A>
struct max_return<A&,A&>{
  using type=A&;
};
template<class A, class B>
using max_return_t = typename max_return<A,B>::type;

template<class T, class U>
max_return_t<T,U> super_max(T&& t, U&& u) {
  if (t < u)
    return std::forward<U>(u);
  else
    return std::forward<T>(t);
}

它也只使用< ,並且更喜歡領帶上的左手邊。

實例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM