const数组和指向const指针的重载函数

Overload function for both arrays-of-const and pointers-to-const

本文关键字:const 重载 函数 指针 数组      更新时间:2023-10-16

我可以使用如下模板函数捕获数组及其(编译时)大小:

template<int N>
void foo(const int (&)[N]) {
    std::cout << "foo(const int (&)[N])n";
}

然而,我想重载foo,也允许指针指向const,这样第一个重载是在函数在数组类型上调用时使用的,第二个重载是在直接在指针类型上调用时使用的。

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);
}

在ideone上试试

这里,第一个过载是针对a的,第二个是针对b的。

我的猜测是,对于a,编译器必须执行转换到const,这意味着foo(const int *)不是一个完美的匹配,但我失去了为什么这甚至不是一个模棱两可的函数调用。

如何更改代码,以便在两种情况下都调用第一个重载?

为什么不工作

在您的示例中,编译器匹配器会考虑这两个重载。过载解决方案来解决这个问题,消除一个并保持最佳匹配。根据标准草案N4527 13.3.3/1.6最佳可行函数[over.match.best]:

F1不是函数模板特化,F2是函数模板特殊化

在本例中,F1为void foo(const int *), F2template<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]