minmax that returns modifiable references

六眼飞鱼酱① 提交于 2019-12-05 22:11:29

There was a paper kind of along these lines a long time ago, by Howard Hinnant: N2199. Its very opening example demonstrates the precise problem you're trying to solve:

The function can not be used on the left hand side of an assignment:

int x = 1;
int y = 2;
std::min(x, y) = 3;  // x == 3 desired, currently compile time error

It goes on to list as examples the frequently dangling reference problem, mixing types, and being useful with move-only types, and goes on to propose new versions of min and max that address all of these problems - it includes a very thorough implementation at the bottom (which is too long to paste here). Implementing minmax() based on that should be pretty straightforward:

template <class T, class U,
    class R = typename min_max_return<T&&, U&&>::type>
inline
std::pair<R, R>    
minmax(T&& a, U&& b)
{
    if (b < a)
        return {std::forward<U>(b), std::forward<T>(a)};
    return {std::forward<T>(a), std::forward<U>(b)};
}

The paper was rejected at the time. It's possible it could come back though.

Being able to get back mutable references is nice, but being able to avoid dangling references is even nicer. Anonymously quoting from an example I saw recently:

template<typename T> T sign(T); 

template <typename T> 
inline auto frob(T x, T y) -> decltype(std::max(sign(x - y), T(0))) { 
    return std::max(sign(x - y), T(0)); 
} 

This function has undefined behaviour for all inputs (the narrowest contract possible?).

Note that your common implementation has this problem. These cases:

template<class T> struct common<T, T&>{using type = T const&;};
template<class T> struct common<T&, T>{using type = T const&;};
template<class T> struct common<T const&, T>{using type = T const&;};
template<class T> struct common<T, T const&>{using type = T const&;};

all dangle. What this means if I have:

int i = 4;
auto result = your_minmax(i, 5);

result here is a pair<int const&, int const&>, one of which is a reference to i and the other of which dangles. All of these cases have to do using type = T; in order to be safe.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!