如何全局指定boost::asio::streambuf bufferstrm大小

How can I specify the boost::asio::streambuf bufferstrm size globally

提问人:azharuddin khan 提问时间:3/25/2021 更新时间:3/25/2021 访问量:216

问:

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

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

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

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

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

我尝试了以下代码

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

但是它给出错误,因为无法在声明点初始化。

提升 Streambuf

评论


答:

0赞 sehe 3/25/2021 #1

您可以在 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
    {}

亚纲

还可以考虑创建添加初始化的派生类型。

UPDATE 子类理念

事实证明,让一个子类实际与 API 的消费一起工作并不是那么简单,因为所有 API 都对缓冲区参数执行类型推导。类型推导不考虑到基的转换,因此它无法识别派生自 的类。此外,还需要这些重载,因为这是引用的唯一缓冲区类型。streambufstreambufstreambuf

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

  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");

Compiler Explorer 上查看它

被黑的分配器

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");

查看编译器资源管理器

评论

0赞 azharuddin khan 3/25/2021
感谢您的回答,但我忘了提到我在 c++11 下使用 g++,所以相同的代码可以工作??
0赞 sehe 3/25/2021
@azharuddinkhan 如果使用括号,则第二个示例已经有效。在 c++03 中使用现场演示更新了答案