如何将向量的向量传递给期望指向指针的(原始)指针的函数

how to pass a vector of vectors into a function expecting a (raw) pointer to pointers

我有一个接受指向双精度指针的函数:

void Foo(double ** m);  // expects a 3x3 matrix of doubles

是否有可能通过适当的转换和诸如此类的东西,将 std::vector of std::vectors of double 或 std::array of std::array 传递给此函数] 的双?如果是这样,有人可以解释一下吗?

std::vector<std::vector<double>> v(3, std::vector<double>(3));
std::array<std::array<double, 3>, 3> a;

如果函数只接受一个指向 double 的指针,这是可能的。 (通过 v.data() 或 a.data())。但是函数接口中指向指针的指针让我觉得这样的转换可能是不可能的。

谢谢,

亚伦

不能。 double**不指向二维数据。它指向一个指向其他数组的指针数组。即使你能找到编译的演员表,数据布局也完全不兼容。

你必须建立数组,例如:

double* a[3] = {v[0].data(), v[1].data(), v[2].data()};
Foo(a);

如果只是那个函数不匹配,并且它没有在某处的内部循环中调用,(并且您不能更改其签名,就像它是 API 的一部分一样,您不能更改):我能想到的唯一解决方案是拆箱您的矢量。遍历你的向量并提取所有数据并将其放入一个数组中,然后将其提供给你的函数。

显然,这在很多方面都很糟糕,所以如果您有其他选择(特别是重载函数以接受 vector,那么这可能是更好的选择。

尝试以下方法

double **p = new double *[v.size()];

for ( size_t i = 0; i < v.size(); i++ ) p[i] = v[i].data();

Foo( p );

delete [] p;

这是一个演示程序

#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>


int main()
{
    std::vector<std::vector<double>> v =
    {
        { 1.1, 2.2, 3.3 },
        { 4.4, 5.5, 6.6 },
        { 7.7, 8.8, 9.9 }
    };

    double **p = new double *[v.size()];

    double * ( std::vector<double>::*fn )() noexcept = &std::vector<double>::data;

    std::transform( v.begin(), v.end(), p, std::mem_fn( fn ) );

    for ( size_t i = 0; i < v.size(); i++ )
    {
        for ( size_t j = 0; j < v.size(); j++ ) std::cout << p[i][j] << ' ';
        std::cout << std::endl;
    }

    delete [] p;
}

输出为

1.1 2.2 3.3 
4.4 5.5 6.6 
7.7 8.8 9.9 

我认为存在设计问题。您确定 void Foo(double ** m); 需要一个 3x3 的双精度矩阵吗?如果是,那么您需要一些包装函数将 vector<vector<double> > 转换为 double**。无论如何都是错误的做法。

template<class T>
std::vector<T*> make_jagged_array( std::vector<std::vector<T>>& vec ) {
  std::vector<T*> retval;
  retval.reserve(vec.size());
  for(auto&& v:vec)
    retval.push_back(v.data());
  return retval;
}

会将 vector<vector<X>> 转换为 vector<X*>vector<X*>.data() returns 您需要 X**

对 n 个维度执行此操作会很有趣。