在这次访谈中, Stepanov展示了如何max在C++中实现泛型函数.
尝试以面向对象的方式实现一个简单的事情,比如max.我不知道怎么做.使用泛型编程我可以写:
Run Code Online (Sandbox Code Playgroud)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; }(你确实需要&和const&).
为什么需要两次编写代码?这是否需要帮助编译器进行优化或减少错误的约定?是max一种特殊情况下的身体const版本是相同的?
N个参数的函数应该有多少有效const和非const置换来定义完整的API?
首先,你需要非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所做的更具可读性是值得商榷的.
你实际上不需要两个版本.你可以这样写.
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.