【问题标题】:Is there any way/trick to pass std::set to a C API which expects C Array?有什么方法/技巧可以将 std::set 传递给需要 C 数组的 C API?
【发布时间】:2011-11-29 23:51:56
【问题描述】:

有没有办法/技巧将 std::set 传递给需要 C 数组的 C API?

【问题讨论】:

    标签: c++ arrays stl set


    【解决方案1】:

    不是直接的,但是你可以先convert the set to a vector(比如说,vec),然后传递&vec[0],这是一个指向内部向量数组第一个元素的指针。

    使用 C++11,您可以传递 vec.data() 而不是 &vec[0]

    【讨论】:

      【解决方案2】:

      不,但是您可以很快地用您的设置内容填充一个数组。例如,假设 mySet 是与 YOUR_TYPENAME 相同类型的集合:

      YOUR_TYPENAME arr* = new YOUR_TYPENAME[mySet.size()];
      std::copy(mySet.begin(), mySet.end(), arr);
      

      然后只需将 arr 传递给 C API。

      【讨论】:

      • 既然可以使用vector,为什么还要使用new
      • +1。我比vector 更喜欢这个解决方案,因为它不需要中间类型。 但是,当您处理 C API 时,我会使用 malloc(或派生词)分配数组,特别是如果数组可能是 API 内的 freed。
      • @Constantinius,我同意如果将所有权传递给 API,malloc 会比 new 更合适,但我不认为这是常见的情况。不确定中间类型是什么意思,在这两种情况下,您都在创建元素类型的数组。 vector 减少了内存管理问题,尤其是在有可能在某处引发异常的情况下。
      • @Constantinius:“需要中间类型”与什么有什么关系?猜猜看:new YOUR_TYPENAME[...] 也有类型! std::vector 更合适。这个问题没有说明free'ing。
      • @Constantinius,这纯粹是学术性的,因为我们不知道 API 的细节,但一般来说,如果 API 要释放您分配的内存,它必须 准确指定您应该如何分配它。如果碰巧使用了两个 CRT,mallocfree 将不会有多大好处(显然,newdelete 也不会)。因此,在跨 API 边界转移内存所有权的情况下,没有最佳实践——只有严格的定义(假设您无法更改 API)。
      【解决方案3】:

      为了完整起见,当前接受的答案的替代向量如下所示:

      {
        std::vector<YOUR_TYPENAME> arr(mySet.begin(), mySet.end());
        Your_C_API(&arr[0]);
        // memory implicitly freed on next line
      }
      

      我更喜欢这种风格,因为:

      • 减少了一行,并且
      • 它消除了我经常犯的一类错误(即忘记delete)。

      【讨论】:

        猜你喜欢
        • 2010-09-09
        • 1970-01-01
        • 2010-10-23
        • 2010-09-18
        • 2014-01-23
        • 2018-01-02
        • 1970-01-01
        • 2011-06-23
        • 2015-11-29
        相关资源
        最近更新 更多