const-of-const和指向const的指针的重载函数

时间:2015-10-06 07:25:24

标签: c++ arrays templates pointers overloading

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

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

Try it on ideone

此处,a调用第一个重载,b调用第二个重载。

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

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

1 个答案:

答案 0 :(得分:2)

为什么它不起作用

在您的示例中,编译器匹配都会考虑这两个重载。这里有超载解决方案,以消除一个并保持最佳匹配。根据标准草案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";
}

LIVE DEMO

为什么建议的解决方案有效

现在作为评论中已经提到的dyp,如果您按照上面的说明通过引用传递指针,则此匹配会被破坏,因为const int *&无法与int*匹配int[N]