如何将 VLA 传递给函数模板
How to pass a VLA to a function template?
我有以下代码无法遵守。
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.............。
我认为编译器无法推断模板中可变长度数组的大小。另外,不要忘记在使用之前转发声明f
。可变长度数组是 GCC 扩展,您应该收到有关其使用的警告。
问题是 c++ 不支持变量大小数组,仅支持作为编译器扩展。这意味着,标准没有说明应该发生什么,你应该看看你是否可以在编译器的文档中找到,但我怀疑这种极端情况是否被记录下来。
所以,这就是问题所在:
int arr[n];
解决方案是避免它,并使用 c++ 支持的东西,例如 std::vector
.
当您使用可变长度数组 (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);
}
像这样声明你的函数:
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);
或者,您可以在需要时用<algorithm>
中的fill
填充它: std::fill(arr.begin(), arr.end(), 0);
模板参数必须在编译时解析。
具有参数 size_t N
的函数模板无法匹配大小来自运行时输入的任何类型的数组或其他容器。
您需要提供另一个版本的array_1d_ini
,该版本没有大小作为模板参数。
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;
}
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 将重载的成员函数传递给函数模板
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 具有常量引用参数的函数模板专用化
- std::span<const T> 作为函数模板中的参数
- 如何编写一个完美的缩写函数模板?
- 仅在函数模板中为那些定义了函数的类型执行函数
- 如何在C++中伪造虚拟可变参数函数模板?
- 以下代码中的函数模板有什么问题?
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- 将显式实例化的函数模板与转换匹配
- 使用定义函数模板别名
- 函数模板返回类型
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- C++ std::functional 中的可变参数函数模板
- 单行函数模板 c++ 的内联性保证
- C++函数模板需要 &for 数组参数
- 概念解析为使用 std::make_signed_t 时意外的函数模板
- 如何将 VLA 传递给函数模板