1

有些人可能知道也可能不知道您可以使用以下代码获取函数的数组参数的大小:

template<typename DataType, size_t SIZE>
void SortingAlgorithm(DataType (&array)[SIZE])
{
  ...
  return;
}

其中 SIZE 可用于表示数组中元素的数量,允许程序员使用您的函数将数组作为参数传递而无需显式传递长度。例如,程序员可以这样做:

SortingAlgorithm( arrayToBeSorted ); //the length is not passed here, which is fine

对于可以相对容易地以迭代方式实现的算法,这很好。但我试图用其他递归算法来做到这一点。每个人的代码可能如下所示:

template<typename DataType, size_t SIZE>
void SortingAlgorithm(DataType (&array)[SIZE])
{
  DataType newArray[SIZE];
  memcpy(newArray,array, SIZE);  //copy to a new array
  SortingAlgorithm( newArray );
  ...
  return;
}

但是,每次说程序需要不同的参数类型,类型转换失败,并显示尝试对 newArray 数组的 SIZE 说明符进行多次类型转换时,都会引发错误,并且程序失败。但是,如果我在进行递归调用之前使用实际值来定义 newArray 的大小,它不会吐出这些错误,如下所示:

DataType newArray[10]; //arbitrary number, but the compiler accepts this.

为什么可变大小的数组会导致错误?还有无论如何要实现一个递归算法,它接受一个数组作为输入,但不需要数组的长度作为参数,因为它可以在函数调用中每次确定数组的长度?

4

4 回答 4

7

Make a helper function that takes a size, it can be used internally by your other function, and nobody has to know about it. For example:

template<typename DataType>
void SortingAlgorithm_helper(DataType * ptr, size_t size)
{
    ...
    SortingAlgorithm_helper(ptr + 1, size - 1);
    ...
}

template<typename DataType, size_t SIZE>
void SortingAlgorithm(DataType (&array)[SIZE])
{
    ...
    SortingAlgorithm_helper(newArray,SIZE);
    ...      
}

By your comments, you are considering switching to vector. Well, you don't have to make a choice here. You can make the code much more generic to handle both. Instead of passing in a pointer and a size to the helper function, we pass in two iterators designating a range. Then we modify the main function to accept any container, as long as std::begin and std::end work on it.

template<typename Iterator>
void SortingAlgorithm_helper(Iterator first, Iterator last)
{
    ...
    SortingAlgorithm(++first, last);
    ...
}

template<typename Container>
void SortingAlgorithm(Container & c)
{
    ...
    SortingAlgorithm_helper(std::begin(c), std::end(c));
    ...
}

This should handle built-in arrays, std::vector, std::array and std::deque. If you limit the operations performed on the iterators to bi-directional (++ and --), then it should handle std::list as well.

于 2012-11-09T20:44:19.177 回答
4

不要这样做。相反,请使用以下选项之一:

  • 使用一个std::vector(它有一个size()方法)而不是一个数组。
  • Pass in the size of the array as an additional argument to your function.

As for recursive algorithms, don't just copy the elements into a new array, it's time consuming.

Instead, pass in two pointers to the beginning and the end of the portion of the array that you want to process (look at how STL algoritms work, std::sort doesn't take a container, instead it takes two iterators).

Note however, that this actually depends on the details of the algorithm you're using, some algorithms may actually require explicit copying, but you should avoid it when possible.

于 2012-11-09T20:40:33.210 回答
1

The template generates code at compile time, specifying a value like 10 allows it to generate code because it knows what value to use. Specifying something that can not be determined at compile time(like a variable that only has a value at run time) means it doesn't know what value to use when generating code.

于 2012-11-09T20:43:42.890 回答
0

The compiler needs to figure out the sizes at compile time, not run time. My compiler accepts your code as written, but apparently yours can't figure out the size. You can explicitly tell it the size like this:

SortingAlgorithm<DataType, SIZE>( newArray );.

Both versions of that line of code work with my compiler.

于 2012-11-09T20:50:41.690 回答