PiQ*_*uer 7 c++ compiler-errors icc language-lawyer
我在Linux上使用ICC 14.0.2.此代码段与GCC和CLang编译,但不编译ICC:
template<int N, bool B>
struct A;
template<int N>
struct A<N,false>
{
template<int M>
struct Nested {};
};
template<int N>
struct A<N,true> : public A<N,false> {};
template struct A<1,true>::Nested<2>; // explicit instantiation
Run Code Online (Sandbox Code Playgroud)
尝试用三个编译器编译它:
$ g++ -c -std=c++11 testcase.cc
$ clang++ -c -std=c++11 testcase.cc
$ icpc -c -std=c++11 testcase.cc
testcase.cc(17): error: invalid qualifier for "A<1, false>::Nested<2>" (a derived class is not allowed here)
template struct A<1,true>::Nested<2>;
^
compilation aborted for testcase.cc (code 2)
Run Code Online (Sandbox Code Playgroud)
我找不到有关此错误消息的任何有用信息.
在我的例子中,显式实例化(更复杂的类)是单元测试的一部分,我可以通过实例化一个对象来解决问题,ICC愉快地编译:
void foo()
{
A<1,true>::Nested<2>();
}
Run Code Online (Sandbox Code Playgroud)
如果ICC对它的错误或者这是否是编译器错误,我现在仍然想.
谢谢你的时间!
更新 谢谢Filip的详细分析.我向英特尔开发人员报告了这个问题.事实上,部分专业化与问题无关(正如我最初所怀疑的那样),所以即使这个更简单的片段也会重现问题:
template<int N>
struct A
{
template<int M>
struct Nested {};
};
template<int N>
struct B : public A<N> {};
template struct B<1>::Nested<2>;
Run Code Online (Sandbox Code Playgroud)
注意: gcc并clang显示正确的行为......
BUG进来了icc!
gcc和clang接受的片段是合法的,不应触发诊断.
负责icc发布所提供诊断的内部代码的作者可能会跳过下面的片段,取自标准,该片段Base表示依赖于模板参数的名称不应该在Derived类的定义中可用.
14.6.2 从属名称
[temp.dep]3 在类或类模板的定义中,如果基类依赖于 模板参数,则在类模板或成员的定义点或实例化期间,不会在非限定名称查找期间检查基类作用域.类模板或成员.
如上所述,重要的是要注意,[temp.dep]p3在类的定义中没有检查基类范围,它并不表示从外部访问时不会继承这些名称.
你的"解决方法"表明名称(在这种情况下template<int> struct Nested)确实(正确地)继承并在内部可用A<1, true>,但icc似乎混淆了显式实例化与类定义中的名称规则.