[enable_if] problem with Intel 10.0.23

The following is distilled from a much larger code base and exibits a discrepancy between gcc 4.2.0 and the Intel C++ compiler 10.0.23 (both under Linux). GCC compiles the example fine, while the Intel compiler chokes on the last statement, objecting that: ------------------------------ Intel error message ------------------------------ -*- mode: compilation; default-directory: "~/dev/proto_pdl/" -*- Compilation started at Thu Jun 21 16:34:47 /opt/intel/cce/10.0.023/bin/icpc -I. -obe be.cpp be.cpp(15): error: class "boost::enable_if<boost::is_same<B, A>, void>" has no member "type" struct foo<T, typename boost::enable_if<boost::is_same<X,A> >::type> ^ detected during instantiation of class "S<X> [with X=B]" at line 24 be.cpp(15): error: class "boost::enable_if<boost::is_same<B, A>, void>" has no member "type" struct foo<T, typename boost::enable_if<boost::is_same<X,A> >::type> ^ detected during instantiation of class "S<X> [with X=B]" at line 24 compilation aborted for be.cpp (code 2) It seems like the very mechanism on which enable_if is based (SFINAE rule) makes the intel compiler unhappy. The release notes for version 10 have a fragment that is suspicious: New -early-template-check Switch Even though recent versions of g++ (3.4 and newer) parse template definitions, they do very little semantic checking of such definitions. Most of the semantic checking is delayed until an actual instantiation is done. As a result, g++ accepts certain unusable templates provided they are not actually used in the program. A new option is available (-early-template-check) to allow Intel C++ users to check the semantics of function template prototypes before instantiation. Example: class A {}; template <class T> struct B { B () {}; // error with -early-template-check): no initializer for // reference member "B<T>::a" A& a; }; Note that this switch will work in gcc 3.4 and later compatibility modes only (i.e. -gcc-version=340 and later). This leads me to believe that when not in gcc compatibility mode they try to be more agressive and analyze template code prematurely (btw, the code included doesn't compile even with -gcc-version=420). What is the general opinion on the validity of enable_if w.r.t to the standard? Are there known workarounds for the Intel compiler? Best regards, Maurizio ------------------------------ Code ------------------------------ #include <boost/utility/enable_if.hpp> #include <boost/type_traits/is_same.hpp> struct A {}; struct B {}; template<typename X> struct S { template<typename T, typename Enable=void> struct foo { enum { value=0 }; }; template<typename T> struct foo<T, typename boost::enable_if<boost::is_same<X,A> >::type> { enum { value=1 }; }; }; int main () { int i = S<A>::foo<B>::value; int j = S<B>::foo<B>::value; // OK for g++ 4.2.0, NOK for Intel C++ 10.0.23 }
participants (1)
-
Maurizio Vitale