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

时间:2016-10-26 11:40:04

标签: c++ c++11 operator-overloading

我有一个使用Asio的异步方法加载vector<unsigned char>的类。然后我重载了&lt;&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;
    }

其中std::cerr << socket->read_buffer.size() << std::endl;具有正确的大小,并且逐步调试显示其内容也是有效的。

但是当我收到数据时:

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

response为空。我已经尝试将其初始化为预期响应的长度,但我最终得到了一个带有X空字符的缓冲区。

难以接受。不应该将return语句复制或移出值吗?

3 个答案:

答案 0 :(得分:5)

你对

中发生的事情有一个错误的假设
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;

在您的主要代码中。

答案 1 :(得分:3)

我认为您的代码应如下所示:

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块中嵌入所有操作)。

答案 2 :(得分:1)

response << socket;

装置

operator<<(response, socket);

并且以这种形式明确表示您要放弃返回值。

代码使用读取const vector<unsigned char>output的原型进行编译是另一个提示,即您永远不会修改输出向量。

如果你希望它像流插入操作符一样工作 - 附加到左侧并且可以链接,如下所示:

 response << socket << another_socket;

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

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;
}