简体   繁体   English

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

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

I have a function that accepts a pointer to pointer to double: 我有一个函数,它接受一个指向double的指针:

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

Is it somehow possible, with appropriate casting and whatnot, to pass into this function either a std::vector of std::vectors of double or else an std::array of std::arrays of double? 是否可以通过适当的转换和其他方式,将std :: vector的std :: vectors double传递给此函数,或者将std :: array的std :: arrays double传递给此函数? If so, can someone please explain how? 如果是这样,有人可以解释一下吗?

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

If the function accepted only a pointer to double, this would be possible. 如果该函数仅接受一个指向double的指针,则可以这样做。 (via either v.data() or a.data()). (通过v.data()或a.data())。 But the pointer to pointer in the function interface makes me think that such a conversion may not be possible. 但是函数接口中的指针指向使我认为这样的转换可能是不可能的。

Thank you, 谢谢,

Aaron 亚伦

You have to build the array, by example: 您必须构建数组,例如:

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

You can't. 你不能 double** does not point to two-dimensional data. double**不指向二维数据。 It points to an array of pointers to other arrays. 它指向一个指向其他数组的指针数组。 Even if you could find a cast that compiled, the data layouts are simply incompatible. 即使可以找到已编译的演员表,数据布局也完全不兼容。

Try the following 尝试以下

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

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

Foo( p );

delete [] p;

Here is a demonstrative program 这是一个示范节目

#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;
}

The output is 输出是

1.1 2.2 3.3 
4.4 5.5 6.6 
7.7 8.8 9.9 

If it's just that one function that's mismatched, and it isn't called in an inner loop somewhere, (and you can't change its signature, like its part of an API you can't change): the only solution I can think of is to unbox your vector. 如果仅仅是一个函数不匹配,并且没有在某个地方的内部循环中调用它,(并且您无法更改其签名,就像它在API的一部分一样,您就无法更改):我能想到的唯一解决方案的是取消装箱。 Iterate over your vector and pull out all of the data and put it into an array and then feed that into your function. 遍历向量,并提取所有数据并将其放入数组中,然后将其输入函数中。

Obviously, that's nasty in several ways, so if you have another option (notably, overloading the function to accept vector , then that's probably a better choice. 显然,这在很多方面都是令人讨厌的,因此,如果您还有另一种选择(特别是重载该函数以接受vector ,那可能是一个更好的选择。

I think there is a design problem. 我认为有一个设计问题。 Are you sure that void Foo(double ** m); 您确定void Foo(double ** m); expects a 3x3 matrix of doubles? 期望双倍的3x3矩阵? If yes, than you need some wrapper function to convert vector<vector<double> > to double** . 如果是,则需要包装函数将vector<vector<double> >转换为double** Any way it's the wrong approach. 无论如何,这是错误的方法。

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;
}

will convert a vector<vector<X>> into a vector<X*> , and vector<X*>.data() returns you your X** you need. vector<vector<X>>转换为vector<X*>vector<X*>.data()返回您需要的X**

Doing this for n dimensions would be amusing. 对n个维度执行此操作将很有趣。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM