Edit append: The question title was "do Visual Studio compiler or Clang have incorrect behavior"- but that have been changed.
So I add here that clang and gcc compiles it the way I intended, but VS does not.
I have the following code:
template<typename S, typename T, std::size_t... I>
void
print_tuple_like(S& s, const T& t, std::index_sequence<I...>)
{
void* unused[] = { &(s << std::get<I>(t))... };
}
template<typename S, typename T,
std::size_t N = std::tuple_size<decltype(T::children)>::value>
S& operator<<(S& s, const T& t)
{
print_tuple_like(s, t.children, std::make_index_sequence<N>{});
return s;
}
and I get an compiler error:
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\utility(313): error C2338: The C++ Standard doesn't define tuple_size for this type.
1> c:\users\jonas\documents\visual studio 2015\projects\consoleapplication7\consoleapplication7\consoleapplication7.cpp(36): note: see reference to class template instantiation 'std::tuple_size<unknown-type>' being compiled
1> c:\users\jonas\documents\visual studio 2015\projects\consoleapplication7\consoleapplication7\consoleapplication7.cpp(43): note: see reference to function template instantiation 'void print_tuple_like<S,std::tuple<Signature::A,Signature::B>,0,1>(S &,const T &,std::integer_sequence<_Ty,0,1>)' being compiled
1> with
1> [
1> S=std::ostream,
1> T=std::tuple<Signature::A,Signature::B>,
1> _Ty=size_t
1> ]
1> c:\users\jonas\documents\visual studio 2015\projects\consoleapplication7\consoleapplication7\consoleapplication7.cpp(50): note: see reference to function template instantiation 'S &operator <<<std::ostream,Signature,2>(S &,const T &)' being compiled
1> with
1> [
1> S=std::ostream,
1> T=Signature
1> ]
That is because the following code in visual studio:
// TEMPLATE STRUCT tuple_size
template<class _Tuple>
struct tuple_size { // size of non-tuple
static_assert(_Always_false<_Tuple>::value, "The C++ Standard doesn't define tuple_size for this type.");
};
make the substitution failure into a hard failure- making the SFINAE SFIAE
If I remove
static_assert(_Always_false<_Tuple>::value, "The C++ Standard doesn't define tuple_size for this type.");
it works.
Is the code strecthing the c++ standard rules? Or is Microsoft in the wrong?