3

下面是一个MergeSort实现。我的问题是编译器抱怨std::begin不能应用于可变大小的数组 temp以便进一步使用std:copy.

我正在使用 C++17 和gcc 8.3

template<typename Container, typename Iterator>
void Search::MergeSort(Container &array, Iterator begin, Iterator end)
{
    auto const len = end - begin;
    if (len > 1)
    {
        auto mid = begin + len / 2;
        MergeSort(array, begin, mid); 
        MergeSort(array, mid, end); 

        typename Container::value_type temp[len];

        int p = 0;
        for (auto i = begin, j = mid; i < mid; ++i)
        {
            auto curr = *i;
            while (j < end && *j < curr) temp[p++] = *j++;
            temp[p++] = curr;
        }

        auto temp_begin = std::begin(temp); // ! problem: unable to compile this line
        copy(temp_begin, temp_begin + p, begin);
    }

错误消息包括:

template argument deduction/substitution failed:
note: mismatched types 'std::initializer_list<_Tp>' and 'std::vector<int>::value_type*' {aka 'int*'}
      variable-sized array type 'std::vector<int>::value_type [len]' {aka 'int [len]'} is not a valid template argument

在此处输入图像描述

4

2 回答 2

7

是否可以使用std::copy将值从可变大小的 数组复制到容器?

回答你的问题。的,就像@Maxim Egorushkin的回答一样,可以做到。

但是,请不要使用变长数组,因为依赖不属于 C++ 标准的东西是个坏主意。

其次,C++ 提供了更好的选项,例如std::vectors 或std::arrays;因此只需使用它们。

例如,使用std::vector,您可以编写完全没有错误的法律代码(正如评论中提到的@NathanOliver )。

#include <vector>

using value_type = typename Container::value_type;

/* or by iterator_traits
 * using value_type = typename std::iterator_traits<Iterator>::value_type;
 */
std::vector<value_type> temp(len);

如果len本来是编译时知道变量,那么您也可以使用std::array

于 2019-04-26T20:44:18.460 回答
4

问题std::begin/end不是针对可变大小的数组定义的。

可变大小数组是 C99 的一项功能,也是 C++ 的非标准扩展。但是,有时,它们是性能方面的最佳选择。

但是,可以使用普通指针算法获取可变大小数组的迭代器:

std::copy(temp + 0, temp + p, begin);

如果您的 C++ 编译器不支持此扩展,则某些平台(如 Windows、Linux 和可能大多数类 Unix 平台)会提供alloca函数。请注意,这只是一个内存分配函数(类似于malloc),因此它不会调用构造函数或初始化分配的内存。

于 2019-04-26T20:37:54.433 回答