问题描述
这是一个演示程序,其中声明了两个函数,它们都接受对数组的引用。
#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,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,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] )
程序不正确吗?
解决方法
程序正确。这是编译器的错误。
根据 C++ 14 标准(13.3.3.2 Ranking 隐式转换序列)
3 两个相同形式的隐式转换序列是 不可区分的转换序列,除非下列情况之一 适用规则:
(3.1) — 列表初始化序列 L1 是更好的转换 序列比列表初始化序列 L2 如果
(3.1.2) — L1 转换为类型“N1 T 的数组”,L2 转换为类型 “N2 T 的数组”,并且 N1 小于 N2,即使其中一个 否则将适用本段中的规则。
因此根据引用重载函数
void f( const int ( &a )[5] );
将被调用。