英特尔C ++编译器(icpc 14.0):"这里不允许派生类"

时间:2014-03-18 12:37:01

标签: c++ compiler-errors language-lawyer icc

我在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>;

1 个答案:

答案 0 :(得分:7)

注意: gccclang正在显示正确的行为......


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>似乎将显式实例化与规则混淆类的定义中的名称。