c++ - 常量数组和常量指针的重载函数

标签 c++ arrays templates pointers overloading

我可以像这样使用模板函数捕获一个数组及其(编译时)大小:

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

Try it on ideone

这里,第一个重载是为 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 *)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] .

关于c++ - 常量数组和常量指针的重载函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32964090/

相关文章:

c++ - OS X IPC 在 C 中获取进程 ID

c++ - ~ 十六进制数之前的符号

c# - String.join 来自最后一个元素的数组

javascript - 如何将一个数组值映射到另一个数组值以生成结果

c++ - 返回模板类的函数中的C++空尖括号

android - 使用 CMake 为 Android 配置 Qt5 5.7 应用程序

c++ - __syncthreads() 之后的 CUDA 竞赛检查危险

arrays - printf '%s\n' "${array[@]}"每个数组元素打印一行是否正常?

c++ - 在 C++11 中使用 constexpr 和 auto 的冲突声明

c++ - 模板 :Name resolution -->can any one tell some more examples for this statement?