C ++如何声明一个临时未命名的,未初始化的数组?

时间:2014-11-24 08:29:27

标签: c++ arrays c++11

所以我正在编写一个函数,它应该像一个函数一样,返回一个数组(因为你知道不允许在C ++中返回数组),为此我需要一个临时的未命名的,它将被用作默认参数值。隐含的最后一个参数,如下:

template<size_t szArr, typename typeArrs>
auto fnAdd2ArrayElements(const typeArrs (&arr_0)[szArr], const typeArrs (&arr_1)[szArr], typeArrs (&&result)[szArr] = {}) -> typeArrs (&&)[szArr]
{
    for(size_t i(0); i < szArr; ++i)
        result[i] = arr_0[i] + arr_1[i];

    return move(result);
}

正如您所看到的,'result'参数有一个默认参数值,一个未命名的数组,但由于空括号,它总是“零填充”。这会降低性能,因为你可以看到我的功能并不关心它的内容并将填满所有内容。无论如何我可以声明它未初始化。像这样:

template<typename T, size_t sz> using identity = T [sz];

template<size_t szArr, typename typeArrs>
auto fnAdd2ArrayElements(const typeArrs (&arr_0)[szArr], const typeArrs (&arr_1)[szArr], typeArrs (&&result)[szArr] = identity<typeArrs, szArr> ()) -> typeArrs (&&)[szArr]
{
    for(size_t i(0); i < szArr; ++i)
        result[i] = arr_0[i] + arr_1[i];

    return move(result);
}

但上面的代码不会编译。那么任何想法如何做到这一点?

编辑:似乎出现了另一个问题。因为我们返回一个'xvalue'(而不是'prvalue'),如果我们将结果存储在'rvalue'引用中,那么未命名的临时的生命周期就不会像我们按值返回数组一样延伸。这是一个例子:

const int iArr[] = {0, 1, 2, 3, 4};

const int iArr1[] = {0, 1, 2, 3, 4};

int (&&added)[5]  = fnAdd2ArrayElements(iArr, iArr1); //this will create an dangling reference

added[0]; //illegal - accessing dangling reference

3 个答案:

答案 0 :(得分:3)

这会有风险,因为这个临时的生命周期是

template <typename T, size_t N>
struct UninitializedArray
{
    UninitializedArray() {}
    T arr[N];
};

template <size_t szArr, typename typeArrs>
typeArrs (&&)[szArr]
fnAdd2ArrayElements(
    const typeArrs (&arr_0)[szArr],
    const typeArrs (&arr_1)[szArr],
    typeArrs (&&result)[szArr] = UninitializedArray<typeArrs, szArr>{}.arr)
{
    std::cout << result[0] << std::endl; // To check that value is not initialized.

    for (size_t i(0); i < szArr; ++i) {
        result[i] = arr_0[i] + arr_1[i];
    }
    return std::move(result);
}

Live example

答案 1 :(得分:0)

我认为这不是一个很好的方法,因为您无法正确指示返回数组。

另一种方法是重载函数并在该重载内,使用适当定义的数组参数调用另一个函数。 (顺便说一下,这是Java可用的唯一方法)。

答案 2 :(得分:0)

这里的问题是将指针传递给函数会使函数参数衰减为指针(即使你的代码将它们称为引用,它们也是指针)。你不能将指针&#34;返回到一个数组&#34; - 这实际上意味着编译器必须执行memcpy(dest, fnAdd2ArrayElements(...), number_of_bytes);,但它并不知道代码中number_of_bytes的实际长度。

您已使用三个数组参数的代码,因此您可以简单地将函数转换为

void fnAdd2ArrayElements(const typeArrs (&arr_0)[szArr], 
                         const typeArrs (&arr_1)[szArr], 
                         typeArrs (&result)[szArr]);

但是,您必须初始化原始result

或者,这是我的首选解决方案:使用std::vector [或类似]。