【问题标题】:error: passing ‘const string {aka const std::basic_string<char>}’ as ‘this’ argument of ...discards qualifiers [-fpermissive]错误:将‘const string {aka const std::basic_string<char>}’作为 ...discards qualifiers [-fpermissive] 的‘this’参数传递
【发布时间】:2020-07-11 04:24:05
【问题描述】:


我正在尝试使用 Cpprest sdk (Casablanca) 实现 Websocket 客户端。我成功建立了 Web Socket 连接并能够发送/接收消息。响应作为 websocket_incoming_message 的实例接收,该实例有一个方法 extract_string(),其定义为,

_ASYNCRTIMP pplx::task<std::string> web::websockets::client::websocket_incoming_message::extract_string (       )   const

因此它返回 const 字符串。

我正在尝试将此字符串分配给函数本地字符串变量,以便可以将其返回给调用方法。但是,我收到以下错误,

error: passing ‘const string {aka const std::basic_string<char>}’ as ‘this’ argument of ‘std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ discards qualifiers [-fpermissive]

下面是我的代码块,

   std::string WebSocketUtility::send_command(const char* command){

    websocket_outgoing_message o_msg;
     std::string ws_response;

    o_msg.set_utf8_message(command);
    client->send(o_msg).then([](){
        log("Message Sent!!!\n");
    });

    client->receive().then([ws_response](websocket_incoming_message i_msg){ 
           return i_msg.extract_string();
        }).then([ws_response](std::string ws_body){ 
                 ws_response = ws_body;  
        });

   log("WS_RESPONSE:%s:\n",ws_response.c_str());
    return ws_response;
  }

我试过了
1.声明 ws_response 作为参考
2.捕获 ws_response 作为 lambda 中的引用
3.将ws_response声明为cpprest json,并将response赋值为json字段(ws_response[U("output")] = json::value::string(ws_body.c_str()))

没有运气。

我在 C++ 方面没有太多编码经验,并且为此苦苦挣扎。

有人可以帮助我了解如何在 lambda 之外捕获此响应,以便我可以将值返回给调用方法吗?

感谢和问候,
斯瓦蒂·德赛

【问题讨论】:

  • "Hence it return, const string" - 这不是 const 在此上下文中的含义。这意味着extract_string() 本身就是const,即它可以在const websocket_incoming_message 对象上调用。 extract_string()的实际返回类型是pplx::task&lt;std::string&gt;(不是std::string),返回值上没有constpplx::task 有一个get() 方法来获取实际的std::string
  • 我认为错误表明有一个 const std::string & A 分配给 std::string & B 这是不允许的,因为修改 B 也会修改 A。该行是已经很复杂了。不给编译器位置吗? _ASYNCRTIMP pplx::task<:string> 是否可以转换为非 const 引用?
  • @ErnieMur OP 所指的constconstextract_string() 声明的末尾。回复:错误信息,你描述的也不是错误的意思。错误是抱怨operator= 被称为const std::string 作为目的地,而不是相反。此外,在分配给 B 之后修改 B 也不会修改 A,这不是 std::string 的工作方式。而_ASYNCRTIMP 不是返回类型的一部分,它只是一个解析为__declspec(dllimport|dllexport) 的宏。返回类型只是pplx::task&lt;std::string&gt;
  • 你的意思是这个,这里会产生类似的错误信息 gcc:: const std::string a; a = someOtherString; ?

标签: c++ websocket stdstring casablanca cpprest-sdk


【解决方案1】:

[ws_response](websocket_incoming_message i_msg){ return i_msg.extract_string(); }

上面的 lambda 完全没有理由捕获 ws_response,因为它不使用 ws_response 做任何事情。

[ws_response](std::string ws_body){ ws_response = ws_body; }

上面的lambda需要通过引用捕获ws_response才能正确修改。 lambda 当前的编码方式,它捕获ws_response 按值copy,并且 copyconst,因为 lambda未声明为 mutable。这就是您收到编译器错误的原因 - 您试图将 ws_body 分配给 lambda 本地的 const std::string 对象,而不是分配给在 send_command() 中声明的 ws_response 变量。上面的 lambda 大致等价于:

const std::string ws_response_copy = ws_response;
ws_response_copy = ws_body; // <-- ERROR

试试这个:

client->receive().then([](websocket_incoming_message i_msg){ 
    return i_msg.extract_string();
}).then([&ws_response](std::string ws_body){ 
    ws_response = ws_body;  
});

或者,extract_string() 返回一个pplx::task&lt;std::string&gt;,它有一个get() 方法来检索实际的std::string,等待它可用。所以上面可以简化为:

client->receive().then([&ws_response](websocket_incoming_message i_msg){ 
    ws_response = i_msg.extract_string().get();
});

【讨论】:

  • 很好的解释。我从未在 C++ 中使用过 lambda,因此我试图找出错误可能在哪里(在我阅读您的答案之前)。我找不到,因为 ws_response 没有定义 const 并且对我来说并不明显在两者之间有一个 const 副本。你做了两个修改。我猜第一次使用 ws_response 没有任何赋值不会导致任何错误?它只是第二个 lambda?
  • @ErnieMur 是的,这是第二个无法编译的 lambda,您的编译器应该已经向您指出了这一点。查看this reference 了解什么是 lambda 以及它是如何工作的。
  • 感谢您的建议。我之前尝试过通过引用捕获。编译会成功,但是 ws_response 中没有捕获该值。我在 lambda 之外打印 ws_response,它一直是空的。 “或者,extract_string() 返回一个 pplx::task<:string>,它有一个 get() 方法来检索实际的 std::string,等待它可用。”,这引发了一个想法,我可能没有等待响应可用。
  • 添加如下wait()方法,client->receive().then([&ws_response](websocket_incoming_message i_msg){ ws_response = i_msg.extract_string().get(); }).wait ();我现在能够捕获变量中的响应。谢谢你的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多