避免接受lambda的方法的const / non-const重复

时间:2018-05-05 17:48:29

标签: c++ c++11 lambda const

Fruit <- c(rep("Apple",3),rep("Orange",5)) Bug <- c("worm","spider","spider","worm","worm","worm","worm","spider") group <- rep(LETTERS[1:2], each = 4) df <- data.frame(Fruit,Bug, group) 表示像素类型为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(分别使用lambda签名iterate(f)fc(const P&))。我可以复制整个函数体并将f(P&)附加到签名上,但有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

无法推断出成员函数的const。但是,使用转发引用允许推断函数参数的cost。因此,您可以委托将对象类型作为参数并转发所有其他参数的函数。这样重复的代码变得微不足道。如果该功能需要访问privateprotected成员,您只需将其设为(可能是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的特化,你需要约束函数,但这很容易完成。

我个人的偏好是无论如何只有琐碎的成员,并将任何非平凡的任务委托给通用算法。我的偏好是类只维护它们的不变量,有趣的用途是通过算法实现的。