在两个函数之间选择一个重载函数,这两个函数都有一个数组引用类型的参数
Posted
技术标签:
【中文标题】在两个函数之间选择一个重载函数,这两个函数都有一个数组引用类型的参数【英文标题】:Selecting an overloaded function between two functions that both have a parameter of the type reference to an array 【发布时间】:2021-08-12 00:54:03 【问题描述】:这是一个演示程序,其中声明了两个函数,它们都接受对数组的引用。
#include <iostream>
void f( const int ( &a )[5] )
std::cout << "void f( const int ( &a )[5] )\n";
void f( const int ( &a )[6] )
std::cout << "void f( const int ( &a )[6] )\n";
int main()
f( 1, 2, 3 );
return 0;
正如所见,第一个函数声明是
void f( const int ( &a )[5] );
第二个函数声明是
void f( const int ( &a )[6] );
而函数调用表达式为
f( 1, 2, 3 );
尝试使用 www,ideone.com 上的编译器 C++14 (gcc 8.3)
编译此程序我收到错误
prog.cpp:15:17: error: call of overloaded ‘f(<brace-enclosed initializer list>)’ is ambiguous
f( 1, 2, 3 );
^
prog.cpp:3:6: note: candidate: ‘void f(const int (&)[5])’
void f( const int ( &a )[5] )
^
prog.cpp:8:6: note: candidate: ‘void f(const int (&)[6])’
void f( const int ( &a )[6] )
程序不正确吗?
【问题讨论】:
【参考方案1】:程序是正确的。这是编译器的错误。
根据 C++ 14 标准(13.3.3.2 排序隐式转换序列)
3 两个相同形式的隐式转换序列是 不可区分的转换序列,除非以下之一 规则适用:
(3.1) — 列表初始化序列 L1 是更好的转换 序列比列表初始化序列 L2 if
(3.1.2) — L1 转换为类型“N1 T 的数组”,L2 转换为类型 “N2 T 的数组”,并且 N1 小于 N2,即使其中之一 否则将适用本段中的规则。
因此根据引用重载函数
void f( const int ( &a )[5] );
将被调用。
【讨论】:
【参考方案2】:一些编译器可能会在
处给出警告
f( 1, 2, 3 );
对函数 f 的调用是模棱两可的。但程序应该编译。
只要函数调用包含长度void f( const int ( &a )[5] );。
一旦您在数组中引入第 6 个元素,它将调用 void f( const int ( &a )[6] );
还要提到传递的参数,因为 a
在两个定义中都没有使用。如果你没有使用那个论点,那么下面的定义也应该起作用。
void f( const int ( & )[5] )
【讨论】:
以上是关于在两个函数之间选择一个重载函数,这两个函数都有一个数组引用类型的参数的主要内容,如果未能解决你的问题,请参考以下文章
[ C++ ] C++类与对象(中) 类中6个默认成员函数 -- 运算符重载