我在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
尝试使用三个编译器进行编译:
$ 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)
我找不到有关此错误消息的任何有用信息。
在我的例子中,显式实例化(更复杂的类)是单元测试的一部分,我可以通过实例化一个对象来解决这个问题,而ICC很乐意编译它:
void foo()
{
A<1,true>::Nested<2>();
}
如果ICC对其错误或者这是否是编译器错误,我现在还想。
谢谢你的时间!
更新 谢谢Filip的详细分析。问题I reported给英特尔开发人员。事实上,部分专业化与问题无关(正如我最初所怀疑的那样),所以即使是这个更简单的片段也会重现问题:
template<int N>
struct A
{
template<int M>
struct Nested {};
};
template<int N>
struct B : public A<N> {};
template struct B<1>::Nested<2>;
答案 0 :(得分:7)
注意: gcc
和clang
正在显示正确的行为......
BUG在icc
!
gcc 和 clang 接受的摘录是合法的,不应触发诊断。
负责发布所提供诊断的icc
内部代码的作者可能会跳过下面的代码段,取自标准版,其中Base
中的名称取决于 {-1}}类的定义中不应提供> template-parameter 。
14.6.2 从属名称
Derived
3 在类或类模板的定义中,如果基类依赖于 template-parameter ,期间不会检查基类范围 在类的定义点处进行非限定名称查找 模板或成员或在类模板或实例化期间 会员。
如上所述,重要的是要注意[temp.dep]
表示基类范围未在类的定义中检查,它没有&#39 ; t表示从外部访问时不会继承这些名称。
你的&#34;解决问题&#34;显示名称(在本例中为[temp.dep]p3
)确实(正确)继承并在template<int> struct Nested
中可用,但A<1, true>
似乎将显式实例化与规则混淆类的定义中的名称。。