首页 > 解决方案 > 如何全局指定 boost::asio::streambuf bufferstrm 大小

问题描述

我知道我们可以在某些函数中指定 streambuf 的大小,如下所示

boost::asio::streambuf bufferstrm(512);

但是在课堂上我们怎么能做同样的事情

class test{
      public:
          boost::asio::streambuf bufferstrm;
      void func1(){
          //statement
      }
      void func2(){
          //statement
      }
};

所以我的问题是,如果我们boost::asio::streambuf bufferstrm;在上面的类中声明了,那么我们如何指定 bufferstrm 的大小,以便它可以用于类的所有函数。

我试过下面的代码

class test{
      public:
          boost::asio::streambuf bufferstrm(1024);  // specified the size
      void func1(){
          //statement
      }
      void func2(){
          //statement
      }
};

但它给出的错误是不能在声明点初始化。

标签: booststreambuf

解决方案


可以在 C++14 及更高版本中使用正确语法的 NSMI:

class test {
  public:
    boost::asio::streambuf bufferstrm { 1024 }; 

事实上,这只不过是构造函数初始化列表项的简写,采用 c++03 风格

class test {
  public:
    boost::asio::streambuf bufferstrm;

    test()
       : bufferstrm (1024) // base/member initializer list
    {}

子类

您还可以考虑创建一个派生类型来添加初始化。

更新子类的想法

事实证明,让子类真正与 API 的消费一起工作并不是那么简单,streambuf因为所有 API 都对缓冲区参数执行类型推导。类型推导不考虑转换为基,因此无法识别从streambuf. 此外,您需要这些重载,因为这streambuf是唯一通过引用获取的缓冲区类型。

我可以看到两种解决方案:

  1. 提供转换为basic_streambuf_ref<>
  2. 通过专门basic_streambuf<myalloc>用于人工分配器类型来破解它,只是为了添加初始化语义。

转换为basic_streambuf_ref<>

你必须明确地调用它,但这可能不是最糟糕的:

struct mystreambuf : boost::asio::streambuf
{
    using base_type = boost::asio::streambuf;
    mystreambuf() : base_type{1024} {}

    auto ref()
    {
        return boost::asio::basic_streambuf_ref<std::allocator<char>>{
            *static_cast<base_type*>(this)};
    }
};

用作:

using boost::asio::ip::tcp;
tcp::socket sock(boost::asio::system_executor{}, {{}, 7878});

mystreambuf msb;
read_until(sock, msb.ref(), "\r\n\r\n");

在编译器资源管理器上查看

被黑的分配器

template <typename T>
struct myalloc : std::allocator<T> {};

template <typename T>
struct boost::asio::basic_streambuf<myalloc<T>>
    : boost::asio::basic_streambuf<std::allocator<T>>
{
    basic_streambuf() : base_type(1024) {}

    using base_type = boost::asio::basic_streambuf<std::allocator<T>>;
    using base_type::base_type;
    using base_type::operator=;
};

using mystreambuf1024 = boost::asio::basic_streambuf<myalloc<char>>;

然后可以用作

mystreambuf1024 msb;
read_until(sock, msb, "\r\n\r\n");

查看它编译器资源管理器


推荐阅读