[英]Avoiding const/non-const duplication of method accepting a lambda
class Frame<P>
表示像素類型為P
的圖像。 由於其基礎數據緩沖區格式具有多種靈活性,因此遍歷其像素的算法是不平凡的。
template <typename P, bool RM = true> // P is pixel type; RM = is_row_major
class Frame {
// ...
template<typename F>
void iterate(F f) { // iterate in a way that is performant for this buffer
if (stride == (RM ? size.w : size.h)) {
auto n = size.area();
for (index_t k = 0; k < n; k++) {
f(view[k]);
}
}
else {
auto s = static_cast<index_t>(stride)*(RM ? size.h : size.w);
for (index_t k0 = 0; k0 < s; k0 += stride) {
auto m = k0 + (RM ? size.w : size.h);
for (index_t k = k0; k < m; k++) {
f(view[k]);
}
}
}
}
}
我希望能夠同時調用iterate(fc) const
和iterate(f)
(分別具有lambda簽名fc(const P&)
和f(P&)
)。 我可以復制整個函數主體並將const
附加到簽名,但是有更好的方法嗎?
不能推斷成員函數的const
。 但是,使用轉發引用可以推斷出函數參數的cost
。 因此,您可以僅委托給以對象類型作為參數並轉發所有其他參數的函數。 這樣,重復的代碼就變得微不足道了。 如果該函數需要訪問private
成員或protected
成員,則只需使其成為(可能是private
) static
成員即可:
template <typename T, bool PM = true>
class Frame {
template <typename F1, typename F2>
static void iterateTogether(F1&& f1, F2&& f2) {
// actual implementation goes here
}
public:
template <typename F2>
void iterateTogether(F2&& other){
iterateTogether(*this, std::forward<F2>(other));
}
// ...
};
上面使用的實現方式還允許參數具有不同的const
性。 如果您想將參數限制為實際上只是Frame
的特化,則需要限制功能,但是此功能很容易實現。
我個人的喜好是無論如何都只有平凡的成員,並且將非平凡的東西委派給泛型算法。 我的喜好是類僅保持其不變性,並且有趣的用法是通過算法實現的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.