【问题标题】:Is it possible to pass a dynamically allocated array to a function that requires an array reference?是否可以将动态分配的数组传递给需要数组引用的函数?
【发布时间】:2021-06-15 20:16:37
【问题描述】:

提前说明:我知道按照我的要求去做不是一个好主意。这只是出于病态的语言好奇心,而不是实际使用中的问题。我在这里应用的规则是完全任意的。

假设我们有一个完全定义如下的函数。不得将其更改为除此之外的任何内容,不允许模板或函数重载。这个函数的实现也不能改变(并且可以被视为未知)。但是我们知道该参数被用作输出参数。

void my_func(int (&arr)[10]);

在另一个函数中,我们动态分配一个数组。这个分配也不能改变,我们不允许在栈上分配。也不允许进一步分配。

int* my_arr = new int[10];

是否有可能以某种方式调用my_func 并将其传递给my_arr?换句话说,是否有可能欺骗类型系统将my_arr 视为数组而不是指针?

朴素的铸件不会成功,它们都会导致编译错误:

my_func((int[10])my_arr);
my_func(static_cast<int[10]>(my_arr));
my_func(reinterpret_cast<int[10]>(my_arr));

另一个注意事项:我想欺骗类型系统。我不想从堆栈数组等复制数据。为什么?再次:病态的好奇心。

【问题讨论】:

    标签: c++ arrays pass-by-reference


    【解决方案1】:

    并不是说我会推荐做这种事情......

    #include <iostream>
    
    void my_func(int (&arr)[10])
    {
        std::cout << "Address: " << &arr << std::endl;
        for (int i=0; i<10; ++i)
            std::cout << arr[i] << std::endl;
    }
    
    int main()
    {
        int *ptr=new int[10];
    
        for (int i=0; i<10; ++i)
            ptr[i]=i;
        std::cout << "Pointer: " << ptr << std::endl;
        my_func(*( int (*)[10])ptr);
        return 0;
    }
    

    除了 C 风格的演员表,reinterpret_cast 也应该可以工作。诀窍是首先获取指向数组的指针,然后取消引用它。瞧,对数组的引用。

    【讨论】:

    • 哇哦!实际上(*)( int (*)[10]) 中让我有点困惑。你能向我解释一下这是做什么的吗?为什么( int*[10]) 不起作用?
    • 前者是一个指向十个整数数组的指针。后者是一个由十个指向整数的指针组成的数组。这与您需要(A+B)*C 的原因相同,如果您想在将结果乘以C 之前将AB 加在一起,而A+B*C 不适合您。
    【解决方案2】:

    您可以为此使用reinterpret_cast。使用数组类型的别名以使代码更易于阅读,您将获得类似:

    void my_func(int (&arr)[10])
    {
        for (auto e : arr)
            std::cout << e << " ";
    }
    
    int main()
    {
        using array_t = int[10];
        int* my_arr = new int[10]{1,2,3,4,5,6,7,8,9,10};
        my_func(reinterpret_cast<array_t&>(*my_arr));
    }
    

    您可以在live example 看到它正在工作。

    【讨论】:

    • 有趣!我很惊讶my_func(reinterpret_cast&lt;(int[10])&amp;&gt;(*my_arr)); 不起作用。别名似乎不仅更易于阅读,而且在技术上也是必需的。为什么会这样?
    • @Brotcrunsher 这不是必需的,但它让生活更轻松。数组的语法有点复杂,因此要获得对数组的引用,您需要int(&amp;)[10] 和类型中的(&amp;) 告诉编译器&amp; 或引用适用于int[10]。使用 int&amp;[10] 将不起作用,因为那将是一个引用数组,这是不允许的。 (int[10])&amp; 也不起作用,因为就 C++ 语法而言,它完全是错误的。
    猜你喜欢
    • 2017-04-06
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    • 1970-01-01
    相关资源
    最近更新 更多