【问题标题】:How to do achieve "const" and "non-const" overloading without duplicated codes?如何在不重复代码的情况下实现“const”和“non-const”重载?
【发布时间】:2015-01-29 09:24:23
【问题描述】:
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
}

附言

T&amp; entity + pred(const T&amp; entity) + op(const T&amp; entity) 是可以接受的。

const T&amp; entity + pred(T&amp; entity) + op(T&amp; 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

【问题讨论】:

  • 对于T&amp;const T&amp;predop 是否过载?
  • @Bathsheba predop 应该遵循 entity 的常量,但不需要相同,例如我的 T&amp; entitypred(const T&amp; entity) 示例。
  • 我想,你所能做的就是在一个函数中编写 blah 代码。但问得好。
  • 为什么需要非常量重载? IE。它有什么不同?
  • @SanderDeDycker 非 const 用于接受 T&amp; 的某些 opop 可能会导致 T&amp; entity 发生一些变化,所以我希望 T&amp; entity 与 @ 987654343@(当然也可以使用op(const T&amp; entity))。但是应该禁止相反的情况,即const T&amp; entityop(T&amp; entity)

标签: c++ templates c++11 overloading


【解决方案1】:

您可以使用转发参考(又名"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
}

【讨论】:

  • 好的,这个很酷,它有效;但我发现TT const &amp; 时给const T&amp; entityop(const T&amp; entity);你能告诉我为什么吗?我的意思是为什么T&amp;&amp;T const &amp; 而不是const T &amp;
  • @MarsonMao T constconst T 是同一类型,T const&amp;const T&amp; 也是。
  • 哦! T constconst Tconst int* iint* const i 之类的东西无关吗?我应该使用什么关键字来搜索T constconst T 的类型相同?抱歉问了这么多。
  • @MarsonMao 是的,const int* iint const* i 相同,与 int* const i 不同。我认为任何好的 C++ 书籍都包含这些信息。
  • @MarsonMao 你最好把它与完整的上下文作为另一个问题发布。
【解决方案2】:

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

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

【讨论】:

  • @AntonSavin :这是一个不同的问题。这个问题是关于const-ness(或者至少我是这么理解的),而不是关于将右值分配给非常量引用。用const int i = 1; foo(i); 试试你的例子。
  • 当然,如果需要支持rvalues作为Foo的参数,那就另当别论了,@AntonSavin的回答更合适。但是操作中的示例并不表明需要这样做。
  • @MarsonMao :它会 - 用你自己的示例代码试一试,例如。 (假设“工作”是指它会适当地引发错误)
  • 该死,它也有效,你是对的。我想我应该再问一个关于我真正意图的问题...实际上我想直接提供T,例如void Foo(Entity&amp; entity, Pred pred, Op op) and void Foo(const Entity& entity, Pred pred, Op op)`。
  • @MarsonMao : 如果entity 参数没有被模板化,那么你确实需要两个重载。
猜你喜欢
  • 2020-04-07
  • 2011-01-10
  • 1970-01-01
  • 1970-01-01
  • 2011-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多