问题
The answer here does not work for this pattern in C++17:
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 ] );
}
}
Due to the argument passed to the lambda Processor
being const and not matching its signature.
回答1:
You can factor out the function as a static template one and use it inside both. We can use the template to generate both of these functions:
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 ] );
}
}
};
The T&
will deduce Collection&
or Collection const&
depending on the constness of *this
来源:https://stackoverflow.com/questions/56602770/how-to-avoid-code-duplicate-const-and-non-const-collection-processing-with-lambd