【问题标题】:How to represent boost array as a pointer of a type?如何将boost数组表示为类型的指针?
【发布时间】:2019-12-27 11:50:39
【问题描述】:

我正在使用 boost 数组作为缓冲区,并希望将其作为参数传递给函数。我想传递它的方式是将大小确定为另一个参数,以便我可以传递不同大小的缓冲区。目前,我的代码如下:

void DataTransform(boost::array<char, 1024> data) {
    //do something
}

我可以使用普通数组:

void DataTransform(char* data, uint_16 size) {
    //do something
}

我将如何展开 boost 数组以将其表示为指针?

【问题讨论】:

    标签: c++ pointers boost


    【解决方案1】:

    boost::array 有一个 data() method 返回指向数组开头的指针,还有一个 size() method 返回数组中元素的数量:

    DataTransform(some_array.data(), some_array.size())
    

    另一种选择是重新设计您的 DataTransform 方法以在迭代器上工作:

    template<typename T, typename U>
    DataTransform(T begin, U end) {
        for(; begin != end; ++begin) {
            // do something with *begin
        }
    }
    

    然后你可以这样称呼它:

    DataTransform(std::begin(some_array), std::end(some_array))
    DataTransform(some_c_array, some_c_array + some_c_array_size)
    DataTransform(std::begin(some_list), std::end(some_list))
    

    【讨论】:

      【解决方案2】:

      如果您有一个像char arr[SOME_SIZE]; 这样的普通数组,那么arr衰减指向其第一个元素的指针。也就是说,arr 将衰减为&amp;arr[0]

      获取boost::array(或者,就此而言,std::arraystd::vector)的元素的地址也是有效的,并给出相同的结果。

      因此,要获得指向 boost::array 的第一个元素的指针,您只需执行例如&amp;data[0].


      但如果您不想处理指针,还有另一种方法可以解决您的问题:模板。

      您可以使用 value 模板参数作为boost::array 的大小,如

      template<size_t N>
      void DataTransform(boost::array<char, N>& data) { ... }
      

      然后您可以将带有char 任意大小元素的boost::array 传递给函数。大小将由编译器简单推断:

      boost::array<char, 512> data1;
      boost::array<char, 1024> data2;
      ...
      DataTransform(data1);
      DataTransform(data2);
      

      【讨论】:

        【解决方案3】:

        我可以使用普通数组:

        void DataTransform(char* data, uint_16 size) {
            //do something
        }
        

        您也可以使用boost::array 来做到这一点,但这将是一个倒退。有充分的理由,为什么容器管理它们的大小而你不必做簿记。

        如果你想要这个

        void DataTransform(boost::array<char, 1024> data) {
            //do something
        }
        

        要接受不同大小的boost::arrays,我建议通过将其设为模板来参数化大小的函数:

        #include <stdio.h>
        #include <boost/array.hpp>
        
        template <boost::array<char,1>::size_type size>
        void DataTransform(boost::array<char, size> data) {
            //do something
        }
        
        int main(void)
        {
            boost::array<char,10> x;
            boost::array<char,20> y;
            DataTransform(x);
            DataTransform(y);
        

        }

        PS:我对boost::array&lt;char,1&gt;::size_type 也不是很满意,我会就此提出一个新问题...

        【讨论】:

          【解决方案4】:

          您可以使用 c++ 20 std::span&lt;T&gt;,这是对内存中某处 T 类型值的连续序列的非常轻量级的抽象。

          What is a “span” and when should I use one?

          这个容器是为了解决你的问题,你的函数接口可以以非常清晰的方式声明:

          void DataTransform(std::span<char> data) {
              //do something
              for (std::size_t i = 0; i < data.size(); i++) {
                 // ...
              }
          }
          

          你可以这样做:

          boost::array<char, 512>  d1;
          boost::array<char, 1024> d2;
          std::array<char, 512>    d3;
          std::vector<char>        d4(512);
          char                     d5[512];
          
          DataTransform(d1);
          DataTransform(d2);
          DataTransform(d3);
          DataTransform(d4);
          DataTransform(d5); 
          // Pass same buffer of varying size
          DataTransform({d5, 256}); 
          

          参见在线godbolt 示例。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-11-23
            • 1970-01-01
            • 2016-12-31
            • 1970-01-01
            相关资源
            最近更新 更多