|
Boost : |
From: Maurizio Vitale (mav_at_[hidden])
Date: 2007-06-21 16:46:29
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
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk