I cannot understand why the below compiles, that is why the constructor isn't disabled (whereas a static_assert in the body with the same expression would fire if uncommented). Thanks in advance for any clarification! ////////////////// template<typename _Tp, _Tp __v> struct integral_constant { static constexpr _Tp value = __v; typedef _Tp value_type; typedef integral_constant<_Tp, __v> type; constexpr operator value_type() { return value; } }; typedef integral_constant<bool, true> true_type; typedef integral_constant<bool, false> false_type; template<typename _Tp, _Tp __v> constexpr _Tp integral_constant<_Tp, __v>::value; template<bool, typename _Tp = void> struct enable_if { }; template<typename _Tp> struct enable_if<true, _Tp> { typedef _Tp type; }; template<typename, typename> struct is_same : public false_type { }; template<typename _Tp> struct is_same<_Tp, _Tp> : public true_type { }; // Just bits of <type_traits> so far... template<typename...> struct __my_and_; template<typename _B1> struct __my_and_<_B1> : public _B1 { }; template<typename... _Args1> struct Tt { template<typename... _Args2, typename = typename enable_if<__my_and_<is_same<_Args1, _Args2>...>::value>::type> Tt(_Args2...) { //static_assert(__my_and_<is_same<_Args1, _Args2>...>::value, "Error"); } }; struct A { }; A a; Tt<int> t(a); // The static_assert would trigger
I did some further investigation of this. The problem seems *not* to be located in __my_and_, but it seems that the compiler expands is_same<T, U>... for different T, U to the specialization is_same<T, T> in this scenario - which is obviously incorrect. This could be concluded after either removing the is_same<T, T> definition or by changing its value to false. When removing the definition, the occurring error message reveals, that the instantiation of is_same<A, A> instead of is_same<int, A> is tried, thus pointing to an incorrect expansion that does ignore the _Args1 expansion.
Thanks Daniel. Depending on how this issue is resolved - at this point I'm pretty sure it's an actual issue - given also the inconsistency vs the static_assert, I will actually use something similar in the library.
Yeah, this is a tricky one. *** This bug has been marked as a duplicate of bug 48322 ***
I see. Thus for the time being I'm probably going to use something like the workaround suggested by Daniel in private email.