如何在没有重复代码的情况下实现 "const" 和 "non-const" 重载?

How to do achieve "const" and "non-const" overloading without duplicated codes?

template <typename T, typename Predicate, typename Operation>
void Foo(T& entity, Predicate pred, Operation op)
{
    if (pred(entity))
    {
        op(entity);
    }

    // and blah
}
template <typename T, typename Predicate, typename Operation>
void Foo(const T& entity, Predicate pred, Operation op)
{
    if (pred(entity))
    {
        op(entity);
    }

    // and blah
}

P.S.

T& entity + pred(const T& entity) + op(const T& entity) 可以接受。

const T& entity + pred(T& entity) + op(T& entity) 应该引发编译错误。

使用 C++11 的解决方案是可以的。


此处示例:

class MyEntity
{
public:
    MyEntity(int e):e(e){}
    int e;
};

MyEntity a = 1234;
MyEntity& ra = a;
const MyEntity& cra = a;
auto pred = [](const MyEntity& i)
{
    return true;
};
auto cop = [](const MyEntity& i)
{
    cout<<i.e<<endl;
};
auto op = [](MyEntity& i)
{
    ++i.e;
    cout<<i.e<<endl;
};
Foo(ra, pred, op);   // ok
Foo(ra, pred, cop);  // ok
Foo(cra, pred, cop); // ok
Foo(cra, pred, op);  // error

您可以使用转发引用(又名 "universal reference"):

template <typename T, typename Predicate, typename Operation>
void Foo(T&& entity, Predicate pred, Operation op)
{
    if (pred(entity))
    {
        op(std::forward<T>(entity));
    }

    // and blah
}

您可以只使用非常量 Foo,而将 const 验证留给特定的 predop

如果 predop 需要非常量 entity,并且 entityconst(如您的第 4 次调用示例代码),编译器将抛出错误。