繁体   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