我可以像这样使用模板函数捕获一个数组及其(编译时)大小:
template<int N>
void foo(const int (&)[N]) {
std::cout << "foo(const int (&)[N])\n";
}
但是,我想重载 foo
以允许指向常量的指针,以便在数组类型上调用函数时使用第一个重载,而当调用数组类型时使用第二个重载它直接在指针上调用。
void foo(const int *) {
std::cout << "foo(const int *)\n";
}
int main() {
int a[1] = { 0 };
foo(a);
const int b[1] = { 0 };
foo(b);
}
这里,第一个重载是为 a
调用的,第二个重载是为 b
调用的。
我的猜测是,对于 a
,编译器必须执行转换为 const,这意味着 foo(const int *)
不是完美匹配,但是我不知道为什么这甚至不是模棱两可的函数调用。
如何更改代码以便在两种情况下都调用第一个重载?
最佳答案
为什么不起作用
在您的示例中,编译器匹配考虑了两个重载。过载解决方案来拯救以消除一个并保持最佳匹配。根据标准草案N4527 13.3.3/1.6 最佳可行函数 [over.match.best]:
F1 is not a function template specialization and F2 is a function template specialization
在我们的例子中,F1 是 void foo(const int *)
和 F2
是template<int N>
void foo(const int (&)[N])
.因此,F1 将优于 F2,因为 F1 不是模板特化而 F2 是。
解决方案
在第二个重载中通过引用传递指针:
void foo(const int *&) {
std::cout << "foo(const int *)\n";
}
为什么建议的解决方案有效
正如 dyp 已经在评论中提到的那样,如果您如上所示通过引用传递指针,则此匹配将被破坏,因为 const int *&
无法匹配 int*
既不int[N]
.
关于c++ - 常量数组和常量指针的重载函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32964090/