Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

Syntax issue Intel vs. Visual C++

MHlav
Beginner
438 Views

The following code will compile in Visual C++ 2015 Update 1, but not in Intel C++ 2016 Update 2.  It gives the error:

test.cpp
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\type_traits(1692): error: class "std::enable_if<0, void>" has no member "type"
                using enable_if_t = typename enable_if<_Test, _Ty>::type;
                                                                    ^
          detected during:
            instantiation of type "std::enable_if_t<0, void>" at line 10 of "test.cpp"
            instantiation of class "Test<T, Args...> [with T=int, Args=<>]" at line 18 of "test.cpp"

Is Intel C++ wrong?  Thanks.

#include <type_traits>

template <typename T, typename... Args>
class Test
{
public:
 Test(T pT)
 {
 }
 template <typename = std::enable_if_t<sizeof...(Args) != 0>>
 Test(T pT, Args... args)
 {
 }
};

int main()
{
 Test<int> t(0);
 Test<int, int> t2(0, 0);

}

 

0 Kudos
2 Replies
Anoop_M_Intel
Employee
438 Views

Hi Michael

I can reproduce this issue and have escalated this issue to compiler engineering team. Will keep you posted when I hear an update from the engineering team.

Thanks and Regards
Anoop

0 Kudos
Judith_W_Intel
Employee
438 Views

 

To answer your question "Is Intel C++" wrong? Well we don't accept the code but MSVC++ 2015 does so it is a Microsoft compatibility issue. But GNU and Clang don't accept it either so I think you are relying on a Microsoft feature.

I'm not really sure why you are using the default argument but the program works as expected without it. It looks like you are trying to use the default argument as a SFINAE (Substitution Failure Is Not An Error) argument to guide the compiler to pick the right overload when I think what is really happening is that the Microsoft compiler does not instantiate default argument expressions if the candidate is not the best match. So I think you are better off without it (i.e. your code is correct and portable).

Here's a more simple example that compiles with Microsoft but not with GNU, Clang, or Intel:

// Accepted by MSVC++ 2015
// But not by Intel, Clang, or GNU

struct C {};

template <typename...Args>
struct Test
{
   Test();
   template <typename = C::type>
   Test(Args...);
};

int main()
{
  Test<int> t;
  return 0;
}

 

Judy

0 Kudos
Reply