我可以使用模板函数捕获数组及其(编译时)大小,如下所示:
template<int N>
void foo(const int (&)[N]) {
std::cout << "foo(const int (&)[N])\n";
}
但是,我想重载foo
以允许指向const的指针,以便在数组类型上调用函数时使用第一个重载,第二个重载时使用#&} #39; s直接调用指针。
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 *)
不是完美的匹配,但我输了为什么这不是甚至是一个暧昧的函数调用。
如何更改代码,以便在两种情况下都调用第一个重载?
答案 0 :(得分:2)
在您的示例中,编译器匹配都会考虑这两个重载。这里有超载解决方案,以消除一个并保持最佳匹配。根据标准草案N4527 13.3.3 / 1.6最佳可行功能[over.match.best]:
F1不是功能模板专用,F2是功能 模板专业化
在我们的案例中,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]
。