1

我有以下无法编译的代码。

using namespace std;
void f(int);
template<typename T1, size_t N>
void array_ini_1d(T1 (&x)[N])
{
  for (int i = 0; i < N; i++)
  {
    x[i] = 0;
  }
}

如果 main 如下所示,传递数组的正确方法是什么。

int main()
{
  int a;
  cin >> a;
  int n = a / 4;
  f(n);
  return 0;
}

void f(int n)
{
  int arr[n];
  array_ini_1d(arr);
}

错误:没有匹配的函数可以调用 array_ini_1d.......

4

6 回答 6

2

问题是 C++ 不支持可变大小的数组,仅支持作为编译器扩展。这意味着,标准并没有说明应该发生什么,你应该看看你是否可以在编译器的文档中找到,但我怀疑这种极端情况是否被记录在案。

所以,这就是问题所在:

int arr[n];

解决方案是避免它,并使用 c++ 支持的东西,例如std::vector.

于 2014-02-13T08:10:43.553 回答
1

我不认为编译器可以推断出模板中可变长度数组的大小。f另外,在使用之前不要忘记转发声明。可变长度数组是 GCC 扩展,您应该收到有关其使用的警告。

于 2014-02-13T07:49:27.440 回答
1

你可以像这样声明你的函数:

template <typename A, size_t N> void f(A a[N]) {
    for(size_t i = 0; i < N; i++)
        cout << a[i];
}

但是,问题是当你调用函数时,编译器不会推导出模板参数,你必须显式指定它们。

char arr[5] = {'H', 'e', 'l', 'l', 'o'};

int main()
{
    //f(arr); //Won't work
    f<char, sizeof(arr)/sizeof(arr[0])>(arr);
    cout << endl;
    return 0;
}

不幸的是,这破坏了这个想法......

UPD:即使该代码也不适用于具有可变长度的数组,因为长度是在运行时计算的,并且模板参数是在编译时定义的。

UPD2:如果使用std::vector你可以创建它初始化: 或者你可以在需要时vector<int> arr(n, 0); 填充它: fill<algorithm>std::fill(arr.begin(), arr.end(), 0);

于 2014-02-13T08:19:39.230 回答
0

当您使用可变长度数组 (VLA)(编译器扩展)时,编译器无法推断 N。

您必须通过指针传递它并给出大小:

template<typename T>
void array_ini_1d(T* a, std::size_t n)
{
    for (std::size_t i = 0; i != n; ++i) {
        a[i] = 0;
    }
}

void f(int n)
{
    int arr[n];
    array_ini_1d(arr);
}

或使用std::vector. (没有使用扩展名)。这看起来更干净:

template<typename T>
void array_ini_1d(std::vector<T>& v)
{
    for (std::size_t i = 0, size = v.size(); i != n; ++i) {
        a[i] = 0; // or other stuff.
    }
}

void f(int n)
{
    std::vector<int> arr(n); // or arr(n, 0).
    array_ini_1d(arr);
}
于 2014-02-13T10:17:10.000 回答
0

模板参数必须在编译时解析。

带参数的函数模板size_t N无法匹配任何类型的数组或其他大小来自运行时输入的容器。

您将需要提供另一个版本,array_1d_ini它没有将大小作为模板参数。

于 2014-11-03T07:12:46.570 回答
-1
template<typename T, size_t N>
void f(T* a)
{
/* add your code here */
}

int main()
{
    int a[10];
    f<int, 10>(a);
    return 0;
}
于 2014-02-13T07:59:08.227 回答