【发布时间】:2018-09-26 07:48:18
【问题描述】:
您可能(不)知道将std::minmax 与自动和临时参数一起使用可能很危险。例如下面的代码是 UB,因为 std::minmax 返回一对引用,而不是值:
auto fun(){
auto res = std::minmax(3, 4);
return res.first;
}
我想问一下是否有可能使std::minmax 函数安全地运行,或者至少更安全而没有任何开销?我想出了一个这样的解决方案,但我不完全确定它是否等同于当前的minmax,因为生成的程序集对于类似 stl 的实现和我的不同。所以问题是:与std 相关的minmax 的实现可能存在哪些问题/缺点:
//below is std-like minmax
template< class T >
constexpr std::pair<const T&,const T&> std_minmax( const T& a, const T& b ){
return (b < a) ? std::pair<const T&, const T&>(b, a)
: std::pair<const T&, const T&>(a, b);
}
//below is my minmax implementation
template< class T >
constexpr std::pair<T, T> my_minmax( T&& a, T&& b ){
return (b < a) ? std::pair<T, T>(std::forward<T>(b), std::forward<T>(a))
: std::pair<T, T>(std::forward<T>(a), std::forward<T>(b));
}
正如你们中的一些人声称不清楚我在问什么,我想改写一下我想要的。我想编写与std::minmax 完全相同的函数,但如果给定一个临时值 - 返回std::pair<T, T> 而不是std::pair<const T &, const T &>。其次,在执行此操作时,我希望避免任何不必要的移动、复制数据等。
【问题讨论】:
-
非常量引用更喜欢第二次重载。混合左值/右值难以推断。可能还有更多。
-
@PasserBy 我不建议同时使用它们。我问的是第一个和第二个之间的意外行为或性能差异。混合 lval/rval 是真的,我怎么能减轻它?
-
@DanielLangr:没有内联的
minmax与int进行比较是没有意义的,因为它将被内联。 -
使用 2 个不同的模板参数,您会遇到返回值类型的问题(是的
std::common_type可能会有所帮助,但也必须处理 constness,结果可能会令人惊讶/不直观)... -
IIUC,您希望得到的
pair成员为 1) 对相应函数参数的 (const) 左值引用,如果这是一个左值或 2) 从该参数移动的值,如果它是一个右值。这样对吗?只是为了澄清。