为什么我的重载<<没有返回任何数据?

Why is my overloaded << not returning any data?

本文关键字:lt 任何 数据 返回 我的 为什么 重载      更新时间:2023-10-16

我有一个类,它使用Asio的异步方法加载vector<unsigned char>。然后我使<lt;运算符返回该数据。

问题是,即使缓冲区已满且有效,运算符也不会返回任何数据。

我的缓冲区:vector<unsigned char>read_buffer;

操作员声明:

friend std::vector<unsigned char> operator<<(const vector<unsigned char>output, const shared_ptr<Socket>socket) noexcept;

实施:

std::vector<unsigned char> operator<<(const vector<unsigned char>output,
                                           const shared_ptr<Socket>socket) noexcept {
      std::cerr << output.size() << std::endl;
      std::cerr << socket->read_buffer.size() << std::endl;
      return socket->read_buffer;
    }

其中CCD_ 3具有合适的大小,并且逐步调试表明其内容也是有效的。

但当我取回数据时:

vector<unsigned char> response;
response << socket;

response为空。我试着将它初始化为预期响应的长度,但最终得到的缓冲区只有X个空字符。

被这个绊倒了。return语句不应该复制或移出值吗?

您对中发生的事情有一个错误的假设

response << socket;

当您执行上述操作时,operator <<的返回不会分配给response。相反,响应是运算符的左手边,套接字是右手边,因为它是二进制运算符。返回值本身将通过类似的操作来捕获

auto foo = response << socket;

但这不是你想要做的。你想做的是像对待cout这样的流对象一样处理左手边,并直接操纵它。我们这样做的方法是更改operator <<的签名和一点正文。首先,我们需要通过引用传递矢量,因为你想修改它,所以我们有

std::vector<unsigned char>& operator<<(const vector<unsigned char>& output,
                                       const shared_ptr<Socket>socket) noexcept
                          ^        lvalue references here         ^

然后我们改变主体,将向量从socket分配到output,然后我们返回类似的输出

{
    std::cerr << output.size() << std::endl;
    std::cerr << socket->read_buffer.size() << std::endl;
    output = socket->read_buffer;
    return output;
}

真的,尽管我认为最好只是进行构建或分配,而不是让操作员过载。你可以有

vector<unsigned char> response(socket->read_buffer);
// or
vector<unsigned char> response;
// stuff
response = socket->read_buffer;

在您的主代码中。

我认为您的代码应该是这样的:

std::vector<unsigned char>& operator<<(vector<unsigned char>& output,
                                           const shared_ptr<Socket>socket) {
      std::cerr << output.size() << std::endl;
      std::cerr << socket->read_buffer.size() << std::endl;
      output = socket->read_buffer;
      return output;
    }

正如注释中所提到的,第一个参数是获取操作结果的参数,您永远不会更改它。此外,也可以省略noexcept,除非您保证不会抛出异常(例如,将所有操作嵌入try/catch块中(。

response << socket;

operator<<(response, socket);

在这种形式中,很明显,您正在丢弃返回值。

该代码与读取const vector<unsigned char>output的原型一起编译,这是您永远不会修改输出向量的另一个提示。

如果你想让它像流插入操作符一样工作——附加到左侧并可链接,就像这样:

 response << socket << another_socket;

第一个参数应该是一个非常数引用,并且应该返回一个对同一对象的非常数引用:

vector<unsigned char>& operator<<(vector<unsigned char>& output,
                                  const shared_ptr<Socket>socket) noexcept 
{
      output.insert(output.end(), socket->read_buffer.begin(), socket->read_buffer.end());
      return output;
}