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++ - 可变参数函数的内联

c++ - 模板特化可以进入我的 .cpp 吗?

c++ - Windows 上 C++ 中的位图操作

php - 按最后一个字符拆分字符串并保存到数组?

Javascript:如何检测数组调用?

python - 过滤 numpy 数组以仅保留给定值的一行

c++ - "Undefined symbols"简单模板类的链接器错误

c++ - 启用视觉样式的日期和时间选择器 -> 更改标题的背景颜色

c++ - 具有非类型模板参数成员函数的模板类

c++ - 无法在 Visual Studio 2015 中将 typedef 转换为 std::pair