如何在没有重复代码的情况下实现 "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
验证留给特定的 pred
和 op
。
如果 pred
或 op
需要非常量 entity
,并且 entity
是 const
(如您的第 4 次调用示例代码),编译器将抛出错误。
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
验证留给特定的 pred
和 op
。
如果 pred
或 op
需要非常量 entity
,并且 entity
是 const
(如您的第 4 次调用示例代码),编译器将抛出错误。