为什么使用const引用参数需要重复代码?

sev*_*evo 13 c++

在这次访谈中, Stepanov展示了如何max在C++中实现泛型函数.

尝试以面向对象的方式实现一个简单的事情,比如max.我不知道怎么做.使用泛型编程我可以写:

template <class StrictWeakOrdered>
inline StrictWeakOrdered& max(StrictWeakOrdered& x,
StrictWeakOrdered& y) {
return x < y ? y : x;
}

and
template <class StrictWeakOrdered>
inline const StrictWeakOrdered& max(const StrictWeakOrdered& x,
const StrictWeakOrdered& y) {
return x < y ? y : x;
}
Run Code Online (Sandbox Code Playgroud)

(你确实需要&和const&).

为什么需要两次编写代码?这是否需要帮助编译器进行优化或减少错误的约定?是max一种特殊情况下的身体const版本是相同的?

N个参数的函数应该有多少有效const和非const置换来定义完整的API?

Bau*_*gen 7

首先,你需要非const版本来允许这样的东西

max(a, b) = something;
Run Code Online (Sandbox Code Playgroud)

如果您不想这样做,您只需提供const版本以涵盖所有情况.这基本上就是标准的std::max作用.

如果所有输入都是非输入,则所有其他情况都由版本正确处理,您也不需要提供任何更多const和非const返回的排列.const&constconst

如果您想避免代码重复,可以执行以下操作:

template <class StrictWeakOrdered>
inline StrictWeakOrdered& max(StrictWeakOrdered& x, StrictWeakOrdered& y) {
    const auto &xr = x;
    const auto &yr = y;
    return const_cast<StrictWeakOrdered&>(max(xr, yr));
}
Run Code Online (Sandbox Code Playgroud)

在这种特殊情况下,这const_cast是安全的,因为您已经知道输入确实是非的const.现在您只需提供const案例的实现.

因此,不需要提供两次实现,并且不应该帮助编译器,但是上述是否比Stepanov所做的更具可读性是值得商榷的.


Yam*_*vic 7

你实际上不需要两个版本.你可以这样写.

template <class S, class T>
decltype(auto) max(S&& a, T&& b) {
    using Ret = std::conditional_t<
          std::is_const<std::remove_reference_t<S>>::value, S, T>;

    if (b < a)
        return std::forward<Ret>(a);
    return std::forward<Ret>(b);
}
Run Code Online (Sandbox Code Playgroud)

const如果其中一个论点是,则回落const.