http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53236
--- Comment #3 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-05-05 18:57:03 UTC --- Reduced test-case: //----- template<typename, typename, typename> struct enable_same {}; template<typename T, typename U> struct enable_same<T, T, U> { typedef U type; }; template <typename ...Ts> struct other_variant { void get(){} }; template <typename T, typename ...Ts> struct other_variant<T, Ts...> : other_variant<Ts...> { T u; using other_variant<Ts...>::get; template <typename T2> typename enable_same<T, T2, T>::type get() { return u; } }; int main() { other_variant<int, double> ov; ov.get<double>(); } //----- It should be added, that it is important that other_variant has a second template argument of double here (e.g. 'bool' won't work): It seems as if within the member template get of the partial specialization T behaves as if it were type double within this member declaration. The hypotheses becomes some evidence, if we change the implementation of the get template as follows: template <typename T2> typename enable_same<T, T2, T>::type get() { typename enable_same<T, double, bool>::type dummy; return u; } This also is accepted, even though T is of type int. The curiosity increases about the interpretation of the deduced type of 'T' within the partial specialization, if we add seemingly contradictory typedefs to the class body of the specialization as follows: //--- template<typename, typename, typename> struct enable_same {}; template<typename T, typename U> struct enable_same<T, T, U> { typedef U type; }; template <typename ...Ts> struct other_variant { void get(){} }; template <typename T, typename ...Ts> struct other_variant<T, Ts...> : other_variant<Ts...> // Line 18 { T u; typename enable_same<T, int, wchar_t>::type dummy1; // L. 22: Should be OK typename enable_same<T, double, char>::type dummy2; // Should be an error using other_variant<Ts...>::get; template <typename T2> typename enable_same<T, T2, T>::type get() { typename enable_same<T, double, bool>::type dummy; // Should be an error return u; } }; int main() { other_variant<int, double> ov; // Line 37 ov.get<double>(); } //--- On gcc 4.8.0 20120429 (experimental) I get the following diagnostics: 18| required from 'struct other_variant<int, double>'| 37| required from here| 22|error: no type named 'type' in 'struct enable_same<double, int, wchar_t>'| 37| required from here| 23|error: no type named 'type' in 'struct enable_same<int, double, char>'| 38| required from here| 30|warning: unused variable 'dummy' [-Wunused-variable]| Note that lines 22 and 23 describe the affected instantiations as enable_same<double, int, wchar_t> and enable_same<int, double, char> thus T seems to be once double and once int within the same instantiation - quite amusing ;-)