简体   繁体   English

符合 C/C++ ISO 的将 void ptr 转换为多维 arrays

[英]C/C++ ISO compliant casting void ptr to multidimensional arrays

I have a function in C++ that looks like:我在 C++ 中有一个 function 看起来像:

//ellipsis are irrelevant variables. Not variadic
lint find_max(const void* ptr, ... , const vector<lint> &nums, ...)
{
    const mm (*arr)[nums.size()] = (const mm (*)[nums.size()]) ptr;
    //or
    const mm (*arr1)[nums.size()] = reinterpret_cast<const mm (*)[nums.size()]>
                                      (ptr);
}


The two casts produce an error with little detail as to why.这两个演员产生了一个错误,几乎没有详细说明原因。

 error: cannot convert ‘const mm (*)[(<anonymous> + 1)]’ {aka ‘const min_and_max (*)[(<anonymous> + 1)]’} to ‘const mm (*)[(<anonymous> + 1)]’ {aka ‘const min_and_max (*)[(<anonymous> + 1)]’} in initialization
   42 |   const mm (*arr)[nums.size()] = (const mm(*)[nums.size()])ptr;
      |                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                  |
      |                                  const mm (*)[(<anonymous> + 1)] {aka const min_and_max (*)[(<anonymous> + 1)]}

If I am not mistaken, both lvalue type and the corresponding cast is similar.如果我没记错的话,左值类型和相应的转换都是相似的。 For future reference, should I have more than 2 dimensions, how can I add them?为了将来参考,我应该有超过 2 个维度,我该如何添加它们? I'm still an amateur in pointer manipulation so this will help alot.我仍然是指针操作的业余爱好者,所以这将有很大帮助。

EDIT this does not produce any errors in g++:编辑这不会在 g++ 中产生任何错误:

typedef long long int lint;

lint pInf = ~((unsigned long long int)0) >> 1;
lint nInf = ~pInf;

typedef struct min_and_max
{
    lint min{pInf};
    lint max{nInf};
}mm;


const lint find_max(const void* ptr, int i, int j, const vector<lint> &nums, 
                    const vector<char> &ops)
{
    const int dim = nums.size();
    const mm (*arr)[dim] = reinterpret_cast<const mm (*)[dim]>
                                      (ptr);

    //algorithm which I haven't figured out yet.
    some_lint_value = arr[i][j].max + arr[i-232414][j+46846].min;

    return some_lint_value;
}

void caller(vector<lint> &nums, vector<char> &ops)
{
    mm arr[ops.size()][nums.size()]; //ISO variable size forbid warn

    for (int i = 1; i <= ops.size(); i++)
      {
         for (int j = 1; j <= nums.size(); j++)
           //looped logic for solving the max/min value for an expression problem
           arr[i][j].max = find_max(arr, i, j, nums, ops);
      }
}

In Standard C++ the array bounds must be constant expressions.在标准 C++ 中,数组边界必须是常量表达式。 Both of your examples are ill-formed.你的两个例子都是不正确的。

The difference in compiler behaviour you observe relates to a non-standard extension provided by your compiler that evidently treats the two cases different;您观察到的编译器行为差异与您的编译器提供的非标准扩展有关,该扩展显然将这两种情况区别对待; consulting your compiler's documentation might be a way to proceed if you want to go further down that avenue.如果您想进一步了解 go,那么查阅编译器的文档可能是一种继续方式。

Of course my advice would be to use standard constructs, then it will work on every compiler and the behaviour is well-documented.当然,我的建议是使用标准构造,然后它将适用于每个编译器,并且行为是有据可查的。


The simplest solution to the requirement of "create a contiguous 2-D array with variable dimensions and pass by reference to a function" is actually to create a vector and bear with the minor inconvenience of using x + y*COLS instead of [x][y] for accessing it. “创建具有可变维度的连续二维数组并通过引用传递函数”的要求的最简单解决方案实际上是创建一个向量并忍受使用x + y*COLS而不是[x][y]的轻微不便[x][y]用于访问它。

The code might look like (pseudocode):代码可能看起来像(伪代码):

lint find_max(vector<mm> &arr2, vector<lint> const& nums, ....otherstuff)
{
    mm& item_at_x_y = arr2[x + y * nums.size()];
}

with caller:与来电者:

void caller()
{
     vector<mm> arr2( nums.size() * ops.size() );
     // populate arr2...
     find_max(arr2, nums, ops...);
}

It would be possible to write a Matrix-like class that allows the [x][y] access syntax, eg see here or google for more examples.可以编写一个类似矩阵的 class ,它允许[x][y]访问语法,例如参见此处或 google 以获取更多示例。

You could make an accessor for using parentheses syntax, eg:您可以制作一个使用括号语法的访问器,例如:

auto arr = [&](size_t y, size_t x) { return arr2[x + y * nums.size()]; };

arr(3, 4) = 5;

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

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