const XX放弃限定符[- fpermissive]

const XX discards qualifiers [- fpermissive]

本文关键字:fpermissive XX 放弃 const      更新时间:2023-10-16

在下面的代码段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; }

CODE NIPPET 4 (compareTo function)

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

参见S5.1.2.5:

lambda表达式的闭包类型有一个公共内联函数描述了参数和返回类型的调用操作符(13.5.4)通过lambda表达式的参数声明子句和分别为尾随返回型。这个函数调用操作符是声明const(9.3.1)当且仅当lambdaexpression为参数声明子句后面没有mutable。两者都不是虚的,未声明的易失性。默认参数(8.3.6)不应该是在lambdaddeclarator的参数声明子句中指定。在lambda表达式上指定的任何异常规范都适用对应的函数调用运算符。一个lambda声明器中的Attribute-specifier-seq属于类型对应的函数调用操作符。[注:引用的名称在lambda声明器的上下文中查找lambda表达式。-end note]

基本上,这意味着生成的函子的操作符()默认为const,并且您已按值捕获,并且捕获的变量是生成的函子的成员。

那么,你有两个选择:

  1. 按引用捕获,而不是按值捕获
  2. 将lambda更改为以下内容(注意参数声明子句后面的mutable):

    [srEndPointAddr](EndPointAddr* o) mutable { ... }

不允许谓词函数(std::remove_if的第三个参数)修改对象。在迭代器上调用的所有方法必须为const。请看这个文档:

函数不能修改其实参。

如果返回值的副本或const指针,可以将getTipcAddress设置为const

简而言之,你得到这个错误是因为你在const实例上调用了一个非const方法:srEndPointAddr是const,但你在它上面调用了非const方法getTipcAddress。您的解决方案是将此方法声明为const,因为它看起来是一个简单的getter,并且可能不会修改对象。