如何将零大小的数组传递给模板函数
How to pass an array of zero size to template function
我有一个引用数组的示例函数。函数定义中的元素数量未知。
template<typename T, std::size_t N>
void someFun(T (&)[N])
{
/* ... */
}
为一个元素的数组调用此函数编译正常。
推导的参数类型是 int (&)[1]
.
int main()
{
int arr[1];
someFun(arr);
}
问题是,当我试图传递零元素数组时。下面的示例显示了代码和错误。
int main()
{
int arr[0];
someFun(arr);
}
编译错误(使用 g++ 7.2):
../src/main.cpp: In function 'int main()':
../src/main.cpp:24:13: error: no matching function for call to 'someFun(int [0])'
someFun(arr);
^
../src/main.cpp:9:6: note: candidate: template<class T, long unsigned int N> void someFun(T (&)[N])
void someFun(T (&a)[N])
^~~~~~~
../src/main.cpp:9:6: note: template argument deduction/substitution failed:
make: *** [src/main.o] Error 1
我假设推导的模板参数类型是 int (&)[0]
,但是这个参数的替换失败了。我可以通过重载 someFun
来绕过。这是我的工作示例:
template<typename T, std::size_t N>
void someFun(T (&)[N])
{
/* ... */
}
template<typename T>
void someFun(T (&)[0])
{
/* ... */
}
int main()
{
int arr[0];
someFun(arr);
}
运行 此代码导致调用 void someFun(T (&)[0])
函数,推导的参数类型为 int (&)[0]
。您能否解释一下为什么我不能对零元素数组使用更通用的解决方案?请不要判断这段代码的原因。这只是一个学习目的的例子。
零大小的数组绝对不是标准的 C++。来自 [dcl.array]:
In a declaration T
D
where D
has the form
D1 [ <em>constant-expression</em><sub>opt</sub> ] <em>attribute-specifier-seq</em><sub>opt</sub>
[...]
If the constant-expression is present, it shall be a converted constant expression of type std::size_t
and its value shall be greater than zero.
GCC 然而提供零长度的数组作为 extension 但因为它们是 non-standard 你不能指望它们与其他语言特性一起工作,例如模板参数推导。您可以为零长度数组显式重载函数。
#include <cstdlib>
template<typename T, std::size_t N>
void someFun(T (&)[N]) {}
template<typename T>
void someFun(T (&)[0]) {}
int main() {
int arr[0];
someFun(arr);
}
这可以在 GCC (7.2.0) 上编译,但不能在 Clang (6.0.0) 上编译。
我有一个引用数组的示例函数。函数定义中的元素数量未知。
template<typename T, std::size_t N>
void someFun(T (&)[N])
{
/* ... */
}
为一个元素的数组调用此函数编译正常。
推导的参数类型是 int (&)[1]
.
int main()
{
int arr[1];
someFun(arr);
}
问题是,当我试图传递零元素数组时。下面的示例显示了代码和错误。
int main()
{
int arr[0];
someFun(arr);
}
编译错误(使用 g++ 7.2):
../src/main.cpp: In function 'int main()':
../src/main.cpp:24:13: error: no matching function for call to 'someFun(int [0])'
someFun(arr);
^
../src/main.cpp:9:6: note: candidate: template<class T, long unsigned int N> void someFun(T (&)[N])
void someFun(T (&a)[N])
^~~~~~~
../src/main.cpp:9:6: note: template argument deduction/substitution failed:
make: *** [src/main.o] Error 1
我假设推导的模板参数类型是 int (&)[0]
,但是这个参数的替换失败了。我可以通过重载 someFun
来绕过。这是我的工作示例:
template<typename T, std::size_t N>
void someFun(T (&)[N])
{
/* ... */
}
template<typename T>
void someFun(T (&)[0])
{
/* ... */
}
int main()
{
int arr[0];
someFun(arr);
}
运行 此代码导致调用 void someFun(T (&)[0])
函数,推导的参数类型为 int (&)[0]
。您能否解释一下为什么我不能对零元素数组使用更通用的解决方案?请不要判断这段代码的原因。这只是一个学习目的的例子。
零大小的数组绝对不是标准的 C++。来自 [dcl.array]:
In a declaration
T
D
whereD
has the form
D1 [ <em>constant-expression</em><sub>opt</sub> ] <em>attribute-specifier-seq</em><sub>opt</sub>
[...]
If the constant-expression is present, it shall be a converted constant expression of type
std::size_t
and its value shall be greater than zero.
GCC 然而提供零长度的数组作为 extension 但因为它们是 non-standard 你不能指望它们与其他语言特性一起工作,例如模板参数推导。您可以为零长度数组显式重载函数。
#include <cstdlib>
template<typename T, std::size_t N>
void someFun(T (&)[N]) {}
template<typename T>
void someFun(T (&)[0]) {}
int main() {
int arr[0];
someFun(arr);
}
这可以在 GCC (7.2.0) 上编译,但不能在 Clang (6.0.0) 上编译。