Intel C ++ Compiler (icpc 14.0): "derived class not allowed here"

I am using ICC 14.0.2 for Linux. This piece of code is compiled using GCC and CLang, but not 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 

Trying to compile this with three compilers:

 $ 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) 

I did not find useful information about this error message.

In my case, explicit instantiation (of more complex classes) is part of the unit test, and I can get around the problem by creating an instance of an object that ICC happily compiles:

 void foo() { A<1,true>::Nested<2>(); } 

However, I would like ICC to be right with its error or it is a compiler error.

Thank you for your time!

Update Thanks to Philip for a detailed analysis. I reported this issue to Intel developers. Indeed, partial specialization has nothing to do with the problem (as I suspected earlier), so even this simpler snippet reproduces the problem:

 template<int N> struct A { template<int M> struct Nested {}; }; template<int N> struct B : public A<N> {}; template struct B<1>::Nested<2>; 
+7
c ++ language-lawyer compiler-errors icc
source share
1 answer

Note: gcc and clang show the correct behavior ...


ERROR IN icc !

The passage accepted by both gcc and clang is legal and should not trigger diagnostics.


The author responsible for the code inside icc that provides the diagnostics provided probably travels through the following snippet taken from the standard, which says that Base names that depend on the template parameter should not be accessible inside the definition of the Derived class.

14.6.2 Dependent Names [temp.dep]

3 In the definition of a template for a class or class, if the base class depends on the template-parameter, the scope of the base class is not considered during an unqualified name lookup either at the definition point of the template class or member or during the creation of a class template or member.


As indicated, it is important to note that [temp.dep]p3 says that the scope of the base class is not considered in the class definition , it does not say that such names are not inherited when access is outside.

Your "work around" shows that the name (in this case template<int> struct Nested ) is indeed (correctly) inherited and accessible inside A<1, true> , but icc seems to confuse explicit creation with name rules inside the class definition.

+7
source share

All Articles