http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51213
Bug #: 51213 Summary: [C++11][DR 1170] Access control checking has to be done under SFINAE conditions Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: daniel.krueg...@googlemail.com CC: ja...@gcc.gnu.org gcc 4.7 20111112 (experimental) in C++11 mode rejects the following code: //--- class C { typedef int type; // Line 2 }; template<class T, class = typename T::type> auto f(int) -> char; template<class> auto f(...) -> char (&)[2]; static_assert(sizeof(f<C>(0)) == 2, "Ouch"); // Line 11 template<class T> auto g(int) -> decltype(typename T::type(), char()); template<class> auto g(...) -> char (&)[2]; static_assert(sizeof(g<C>(0)) == 2, "Ouch"); // Line 19 int main() {} //--- "main.cpp|11|error: static assertion failed: "Ouch"| main.cpp||In function 'decltype ((typename T::type(), char())) g(int) [with T = C; decltype ((typename T::type(), char())) = char; typename T::type = int]':| main.cpp|2|error: 'typedef int C::type' is private| main.cpp|19|error: within this context| main.cpp|19|error: static assertion failed: "Ouch"|" After approval of DR 1170: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1170 access checking has become part of the template substitution process as described in 14.8.2 p8: "If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is one that would be ill-formed if written using the substituted arguments. [ Note: Access checking is done as part of the substitution process. —end note ] [..]" This means as of C++11 above program should be accepted.