是薄的实现安全(使用auto和type_traits重新实现最大)

时间:2012-11-04 15:00:11

标签: c++

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

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

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的类型

2 个答案:

答案 0 :(得分:1)

不,这不安全。这正是编译器警告你的。您返回对临时值的引用(在本例中为4.5)。如果您将结果分配给int &x = max(3, 4,5);之类的内容,x将在此行之后立即成为悬空参考。

答案 1 :(得分:0)

max()的问题一般是你希望它做以下两件事之一:

  1. 选择同源值的最大值并返回对此值的引用。
  2. 选择最大不均匀值并返回转换为最常规类型的结果值。
  3. 在不均匀的情况下返回引用不起作用,因为返回对临时的引用,该引用将在函数调用之前停止存在。在同质情况下返回一个值可能是不可取的。