0
#include <iostream>
#include <type_traits>

#include <boost/type_traits.hpp>

template<typename T, typename U>
struct promote
{
  private:
    typedef typename std::conditional<(sizeof(T) > sizeof(U)), T, U>::type Bigger;
    typedef typename std::add_const<Bigger>::type BConst;

  public:
    //because mingw4.6.2 do not implement std::add_reference
    typedef typename boost::add_reference<BConst>::type type;
};

template<typename T, typename U>
auto max(T const &a, U const &b)->typename promote<T, U>::type
{
  return a > b ? a : b;
}

int main(int argc, char *argv[])
{
  std::cout<<max(3, 4.5)<<std::endl;
  std::cout<<max(4.5, 3)<<std::endl;

  return 0;
}

std :: max of mingw4.6.2

template<typename T>
inline T const& max(T const &a, T const &b)
{
  return a > b ? a : b;
}

これは私に警告メッセージを与えます

main.cpp:27:24:警告:一時への参照を返します[デフォルトで有効]

main.cpp:27:24:警告:一時への参照を返します[デフォルトで有効]

コンパイラはmigw4.6.2、OSはwin764ビットです

2番目のバージョン、スカラー型のみをサポート

template<typename T, typename U>
struct promote
{
   typedef typename std::conditional<(sizeof(T) > sizeof(U)), T, U>::type type;

};

template<typename T, typename U>
inline typename promote<T, U>::type max(T a, U b)
{
  static_assert(std::is_scalar<T>::value, "inhomogeneous max only support scalar type");
  static_assert(std::is_scalar<U>::value, "inhomogeneous max only support scalar type");

  return a > b ? a : b;
}

もう1つの解決策は、SFINAEとboost::mplを使用して「過負荷」を実行することです。実際の場合、std::maxのタイプに明示的に名前を付けるだけだと思います

4

2 に答える 2

1

いいえ、安全ではありません。それはまさにコンパイラがあなたに警告していることです。一時的な値 (この場合は 4.5) への参照を返します。結果を のようなものに代入すると、この行の直後にダングリング リファレンスになりますint &x = max(3, 4,5);x

于 2012-11-04T15:18:10.507 に答える
0

一般的な問題max()は、次の 2 つのいずれかを行うことです。

  1. 同種の値の最大値を選択し、この値への参照を返します。
  2. 不均一な値の最大値を選択し、最も一般的な型に変換された結果値を返します。

不均一な場合に参照を返すことは機能しません。関数の呼び出しがそれを取得する前に存在しなくなる一時への参照が返されるためです。同種のケースで値を返すことは、おそらく望ましくありません。

于 2012-11-04T15:20:34.160 に答える