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;
}

mingw4.6.2 的 std::max

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,操作系统是win7 64bits

第二个版本,只支持标量类型

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;
}

另一个解决方案是使用 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()是您希望它做以下两件事之一:

  1. 选择同质值的最大值并返回对该值的引用。
  2. 选择最大的非同质值并将结果值转换为最一般的类型。

在非同质情况下返回引用不起作用,因为返回了对临时的引用,该引用在函数调用可以抓住它之前将不复存在。在同质情况下返回一个值可能是不可取的。

于 2012-11-04T15:20:34.160 回答