如何使用Lambda避免代码重复const和非const收集处理

时间:2019-06-14 17:27:28

标签: c++ design-patterns const c++17

answer here在C ++ 17中不适用于此模式:

FlutterDriver

由于传递给lambda template <typename Processor> void Collection::ProcessCollection(Processor & processor) const { for( int idx = -1 ; ++idx < m_LocalLimit ; ) { if ( m_Data[ idx ] ) { processor( m_Data[idx] ); } } const int overflowSize = OverflowSize(); for( int idx = -1 ; ++idx < overflowSize ; ) { processor( (*m_Overflow)[ idx ] ); } } // How to avoid this repetition for non-const version? template <typename Processor> void Collection::ProcessCollection(Processor & processor) { for( int idx = -1 ; ++idx < m_LocalLimit ; ) { if ( m_Data[ idx ] ) { processor( m_Data[idx] ); } } const int overflowSize = OverflowSize(); for( int idx = -1 ; ++idx < overflowSize ; ) { processor( (*m_Overflow)[ idx ] ); } } 的参数是const且不匹配其签名。

1 个答案:

答案 0 :(得分:4)

您可以将函数作为静态模板分解出来,并在两者中使用它。我们可以使用模板来生成这两个函数:

struct Collection {
    // ...

    template<typename Processor>
    void ProcessCollection(Processor& processor) {
        ProcessCollectionImpl(*this, processor);
    }

    template<typename Processor>
    void ProcessCollection(Processor& processor) const {
        ProcessCollectionImpl(*this, processor);
    }

    template<typename T, typename Processor>
    static void ProcessCollectionImpl(T& self, Processor& processor) {
        for( int idx = -1 ; ++idx < self.m_LocalLimit ; )
        {
            if ( self.m_Data[ idx ] )
            {
                processor( self.m_Data[idx] );
            }
        }

        const int overflowSize = self.OverflowSize();

        for( int idx = -1 ; ++idx < overflowSize ; )
        {
            processor( (*self.m_Overflow)[ idx ] );
        }
    }
};

T&将根据Collection&的恒定性推论Collection const&*this