Sun Studio 12中的模板编译错误

Jag*_*ath 6 c++ templates partial-specialization sunstudio overload-resolution

我们正在迁移到Sun Studio 12.1并使用新的编译器[CC:Sun C++ 5.10 SunOS_sparc 2009/06/03].编译使用早期版本的Sun编译器[CC:Sun WorkShop 6 update 2 C++ 5.3 2001/05/15]编译好的代码时,我遇到了编译错误.

这是我得到的编译错误.

"Sample.cc":错误:无法找到main()中所需的LoopThrough(int [2])匹配项.1检测到错误.***错误代码1.

码:

#include <iostream> 

#define PRINT_TRACE(STR) \
std::cout << __FILE__ << ":" << __LINE__ << ":" << STR << "\n";

template<size_t SZ>
void LoopThrough(const int(&Item)[SZ])
{
    PRINT_TRACE("Specialized version");
    for (size_t index = 0; index < SZ; ++index)
    {
        std::cout << Item[index] << "\n";
    }
}


/*     
    template<typename Type, size_t SZ>
    void LoopThrough(const Type(&Item)[SZ])
    {
        PRINT_TRACE("Generic version");        
    }
 */  



int main()
{
    {
       int arr[] = { 1, 2 };
       LoopThrough(arr);    
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我使用Generic版本取消注释代码,则代码编译良好,并调用泛型版本.我没有看到禁用扩展的MSVC 2010的这个问题,以及与此处的 ideone相同的情况.调用该函数的专用版本.现在的问题是,这是Sun编译器中的一个错误吗?

如果是,我们如何提交错误报告?

Mar*_*k B 2

在这种情况下,编译器不遵循标准并且存在错误。让我们回顾一下相关部分。

\n\n

首先从 13.3/3 开始我们有:

\n\n
\n

...

\n\n

\xe2\x80\x94 首先,选择候选函数的子集\xe2\x80\x94,这些函数具有\n 适当数量的参数并满足某些其他条件\xe2\x80\x94\n,以形成一组可行的函数(13.3.2)。

\n\n

\xe2\x80\x94 然后,根据将每个参数与每个可行函数的相应参数匹配所需的隐式转换序列 (13.3.3.1) 选择最佳可行函数。

\n
\n\n

因此,这两个函数具有相同数量的参数,并且被视为候选函数。现在我们必须找到最好的可行函数,

\n\n

13.3.3:

\n\n
\n

令 ICSi(F) 表示隐式转换序列,该序列将列表中的第 i 个参数转换为可行函数 F 的第 i 个参数的类型。 13.3.3.1 定义隐式转换序列,\n 13.3.3.2 定义什么这意味着一个隐式转换序列比另一个隐式转换序列更好或更差\n

\n
\n\n

然后我们有

\n\n
\n

给定这些定义,如果对于所有参数,ICSi(F1) 不是比 ICSi(F2) 更差的转换序列,则可行函数 F1 被定义为比另一个可行函数 F2 更好的函数,然后

\n\n

\xe2\x80\x94 对于某些参数 j,ICSj(F1) 是比\n ICSj(F2) 更好的转换序列,或者,如果不是这样,

\n\n

\xe2\x80\x94 F1 是非模板函数,F2 是\n 模板函数特化,或者,如果不是这样,

\n\n

\xe2\x80\x94 F1 和 F2 是模板函数,并且根据 14.5.5.2 中描述的部分排序规则,F1 的函数模板比​​ F2 的模板更专业,或者,如果不是的话,

\n
\n\n

对于第一条规则(添加 const),这两个函数是相等的,而第二条规则不适用(两者都是模板)。所以我们转向第三条规则。从 14.5.5.2(如果需要的话我会引用)我们了解到const int函数的版本比const Item版本更专业,因此最好的匹配是const int重载,然后应该调用它。

\n\n

最好的临时修复可能是第二次过载:

\n\n
template<size_t SZ>\nvoid LoopThrough(int (&Item)[SZ])\n{\n    LoopThrough(static_cast<const int (&)[SZ]>(Item));\n}\n
Run Code Online (Sandbox Code Playgroud)\n