将指向数据的指针作为参数传递给期望二维数组的函数

Esc*_*alo 5 c++

请考虑以下代码

#include<algorithm>
#include<iostream>
#include<array>

void show(double x[2][2]) {
  std::cout<<x[0][0]<<", "<<x[0][1]<<std::endl
           <<x[1][0]<<", "<<x[1][1]<<std::endl;
}

int main() {
  std::array<double, 4> y = {1, 2, 3, 4};  
  double x[2][2];

  // it is safe to copy because x[2][2] consists of
  // four contiguous blocks of memory in row-major order

  std::copy(y.begin(), y.end(), &x[0][0]);

  show(x); // this, obviously, works as expected

  // but how can I cast y, or y.data(),
  // or y.begin() to use the function foo?    
  // show(y); 
}
Run Code Online (Sandbox Code Playgroud)

我正在使用遗留库,其中有许多函数参数x[a][b].但是,我的代码依赖于线性数据表示(也就是说,我只使用C++"线性"容器,例如std::array<T, N>).

想象一下,经过艰苦的计算后,我已经在代码中找到了std::array<double, 2>包含我需要的数据的点,现在我需要调用foo该数据.

我如何"演员"(因为缺少一个更好的词)底层容器,以便我可以调用期望的遗留函数double[2][2]

我真的不想要复制(如示例所示),因为遗留的功能foo被称为数十万次.

作为一个极端的优点,我想将这些遗留函数包装在类似C++算法的接口之后; 类似的东西:

std::vector<std::array<double, 4>> z;
fooify(z.begin(), z.end()); // calls foo(zi) for each zi in z
Run Code Online (Sandbox Code Playgroud)

编辑:一些答案

感谢@ 6502,我开始提供以下解决方案:

#include<algorithm>
#include<iostream>
#include<array>

namespace legacy {
void show(double x[2][2]) {
  std::cout<<x[0][0]<<", "<<x[0][1]<<std::endl
           <<x[1][0]<<", "<<x[1][1]<<std::endl;
}
}

template<size_t N, typename Container>
void show(Container& y) {
  return legacy::show(reinterpret_cast<double(*)[N]>(y.data()));
}

int main() {
  std::array<double, 4> y = {1, 2, 3, 4};  
  show<2>(y);
}
Run Code Online (Sandbox Code Playgroud)

它按预期工作 - 当然,我可以自动推断出"重塑"因素(在这种情况下,它是2,但在一般情况下会有所不同).

然后我将尝试将这个"重构"函数合并到一个算法中.

为了完整起见,我添加了编译细节(OS X 10.7.4使用GCC 4.8.1):

$ g++ example.cpp -std=c++11 -Wall -Wextra
$ ./a.out                                                 
1, 2
3, 4
Run Code Online (Sandbox Code Playgroud)

650*_*502 3

使用C型铸造

show((double (*)[2])y.data());
Run Code Online (Sandbox Code Playgroud)

或者reinterpret_cast如果您想输入更多内容,请使用

show(reinterpret_cast<double (*)[2]>(y.data()));
Run Code Online (Sandbox Code Playgroud)

  • 我认为两者布局不兼容。这次演员阵容将会失败。 (2认同)
  • @WhozCraig:在我看来,这是您应该使用“reinterpret_cast”(或 C 风格强制转换)的完美案例。显然,从哲学的角度来看,2x2 数组与 4 元素数组完全无关,但内存中的布局仍然相同,在这种情况下,您需要告诉编译器忽略类型并信任程序员。 (2认同)