I was very surprised today to discover that Intel's icpc (version 14.0.2, using std=c++0x
) fails to compile the following snippet.
#include <type_traits>
namespace traits_tests {
template<typename>
struct sfinae_true : std::true_type {};
template<typename T>
static auto value_type(int) -> sfinae_true<typename T::value_type>;
template<typename T>
static auto value_type(void*) -> std::false_type;
}
template<typename C>
struct has_value_type
: decltype(traits_tests::value_type<C>(0)) {};
complaining about the last line:
inc/traits.h(258): error: expected an identifier
: decltype(traits_tests::value_type<C>(0)) {};
^
The code works fine with clang
and gcc
.
I don't really fancy a complete re-write to make it work with flawed compilers (why is that always the commercial compilers are flawed?).
icc
?EDIT: Yes, I know that icc
supports decltype
since some time. But in the particular context above, icc
fails to support it. Also note that using std=c++11
instead of std=c++0x
makes no difference.
You can use a template based workaround - any of the standard types that take a template type argument and expose it as a typedef
, then wrap that in a macro that's only defined for ICC e.g.
#ifdef __INTEL_COMPILER
#include <utility>
#define decltype(...) \
std::pair<decltype(__VA_ARGS__), int>::first_type
#endif
Which allows your example to compile without changes.
Once the bug is fixed in all versions of ICC you're using you can remove the macro definition without changing any other code.
(See this answer to a similar MSVC issue)