const XX discards qualifiers [- fpermissive]

5
在下面的代码片段1中,mKnownSRList被定义如下:
std::vector<EndPointAddr*> mKnownSRList;

我看到了代码片段2中的编译错误。请问您能否告诉我这段代码有什么问题呢?getTipcAddress()和compareTo函数的内容如下所示(请参阅代码片段3和4)。

代码片段1(标记了编译错误)

void 
ServiceRegistrarAPI::removeKnownSR(EndPointAddr & srEndPointAddr)
{
   auto last = 
   std::remove_if(mKnownSRList.begin(),
                  mKnownSRList.end(),
                 [srEndPointAddr]( EndPointAddr* o )
                 { 
                    //LINE 355 is the following
            EndPointTipcAddr myTipcAddress = srEndPointAddr.getTipcAddress();
                EndPointTipcAddr otherTipcAddress = o->getTipcAddress();

            return (myTipcAddress.compareTo(otherTipcAddress));
         });

    if(*last != nullptr)
    {
     delete *last;
    }

    mKnownSRList.erase(last, mKnownSRList.end());    
}

片段 2(编译错误)

  ServiceRegistrarAPI.cpp:355:72: error: passing ‘const EndPointAddr’ as ‘this’   argument of ‘EndPointTipcAddr& EndPointAddr::getTipcAddress()’ discards qualifiers [-  fpermissive]

代码片段3(getTipcAddress函数)

EndPointTipcAddr & getTipcAddress() { return mTipcAddress; }

代码片段4 (compareTo函数)


  bool

  EndPointTipcAddr::compareTo(EndPointTipcAddr &rhs) 
  {     
      if( (mType == rhs.getType()) && (mInstanceNo == rhs.getInstanceNo()) )
      {
        return true;
      } 

      return false;
  }

2
还没有详细考虑过这个问题,但我相信这个链接会有相关的信息。 - BoBTFish
3个回答

5
请看 S5.1.2.5:
闭包类型(lambda-expression)的闭包体包含一个公共内联函数调用运算符(13.5.4),其参数和返回类型由闭包类型的 parameter-declaration-clause 和 trailingreturn-type 描述。当且仅当闭包类型的 parameter-declaration-clause 后面没有 mutable 时,这个函数调用运算符声明为 const (9.3.1)。它既不是虚函数也不声明为 volatile。在 lambdadeclarator 的 parameter-declaration-clause 中不能指定默认参数 (8.3.6)。在 lambda-expression 中指定的任何异常规范都适用于相应的函数调用运算符。在 lambda-declarator 中的 attribute-specifier-seq 与相应函数调用运算符的类型相关联。[注意:在 lambda-expression 出现的上下文中查找 lambda-declarator 中引用的名称。——注释结束]
基本上,这意味着生成的函数对象(operator())默认为const,并且您捕获了该变量的值,并且该捕获变量是生成函数对象的成员。
所以您有两个选择:
1. 引用捕获,而不是值捕获。 2. 将您的lambda更改为以下内容(请注意parameter declaration clause后面的 mutable): ``` [srEndPointAddr](EndPointAddr* o) mutable { ... } ```

1
+1e6!终于有人解释了为什么它真的发生了,而不是一些关于其他事情的胡言乱语。 - Red XIII

3
“std::remove_if”函数的第三个参数是一个谓词函数,不允许修改对象。在迭代器上调用的所有方法必须是“const”。请参阅此文档

该函数不得修改其参数。

如果您返回值的副本或一个“const”指针,则可以将“getTipcAddress”设置为“const”。

1
简而言之,您会遇到此错误是因为在这种情况下,您在常量实例上调用非常量方法:srEndPointAddr是常量但您在其上调用了非常量方法getTipcAddress。 您的解决方案是将此方法声明为const,因为它似乎是一个简单的getter,并且可能不会修改对象。

但问题是,“为什么它是一个const实例?” - juanchopanza
@juanchopanza 嗯,我认为问题是如何修复这个错误。 - Ivaylo Strandjev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接