簡體   English   中英

避免接受lambda的方法的const /非const重復

[英]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) constiterate(f) (分別具有lambda簽名fc(const P&)f(P&) )。 我可以復制整個函數主體並將const附加到簽名,但是有更好的方法嗎?

不能推斷成員函數的const 但是,使用轉發引用可以推斷出函數參數的cost 因此,您可以僅委托給以對象類型作為參數並轉發所有其他參數的函數。 這樣,重復的代碼就變得微不足道了。 如果該函數需要訪問private成員或protected成員,則只需使其成為(可能是privatestatic成員即可:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM