为什么cpp-next的这个"min"模板有问题?

Joh*_*itb 21 c++ decltype c++11

我正在阅读cpp-next,其中提供了这个min模板,作为如何将详细的C++代码与python代码进行比较的示例

template <class T, class U>
auto min(T x, U y)->decltype(x < y ? x : y)
{ return x < y ? x : y; }
Run Code Online (Sandbox Code Playgroud)

起初这看起来很无辜,但Daveed Vandevoorde做了这个话

在其返回类型规范中使用decltype的min模板不起作用:它返回一个引用(因为参数是一个左值),它最终引用了大多数常见用法中的局部变量.

我想每个人可能都不清楚这个问题是如何表现出来的.您能否详细解释一下并提供可能的解决方案?

Pup*_*ppy 8

问题是参数不作为参考.这将调用切片,在多态类型的情况下,然后引用返回到局部变量.解决方案是将参数作为右值引用,调用完美转发,然后简单地推导并返回返回类型.完成后,返回引用就好了,因为值仍然存在.

  • +1尝试并且未能为C++ 11执行此操作:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2199.html (2认同)
  • @DaveAbrahams:但是没有尝试返回引用是*错*.你应该可以做一些事情,比如`std :: min(a,b)= 5;`if`a`和`b`都是`int`,例如. (2认同)

ron*_*nag 6

第3版:KonradRudolph

template <class T, class U>
auto min(T x, U y) -> typename std::remove_reference<decltype(x < y ? x : y)>::type
{ 
    return x < y ? x : y; 
}
Run Code Online (Sandbox Code Playgroud)

第2版​​:KennyTM

template <class T, class U>
auto min(T x, U y)->decltype(x < y ? std::declval<T>() : std::declval<U>())
{ 
    return x < y ? x : y; 
}
Run Code Online (Sandbox Code Playgroud)

rev 1:T和U必须是默认的可构造的

template <class T, class U>
auto min(T x, U y)->decltype(x < y ? T() : U())
{ 
    return x < y ? x : y; 
}
Run Code Online (Sandbox Code Playgroud)

测试:

int main()
{
   int x; int y;
   static_assert(std::is_same<decltype(min(x, y)), int>::value, "");
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

编辑:

我有点惊讶,但它实际上编译与remove_reference.