http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50864
--- Comment #8 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2011-10-25 18:08:01 UTC --- (In reply to comment #7) > The arrow operator (vs, eg, +) seems also essential. That makes sense to me, because the code could never be valid, so I would suggest that the keyword is changed to ice-on-invalid-code. The proper code namespace impl { template <class T> T create(); } template < class lhs, class rhs > struct is_arrow_operable_impl { template <class T, class U, class = decltype(impl::create<T>()->*impl::create<U>())> void test(); }; works as expected. I guess the reason for the ICE of the original code is that the compiler runs into a branch where the second impl::create is interpreted as a member access, which could never be valid, because there is no (base) class impl. But this is probably only part of the whole story, because if I change the erroneous example to struct impl { template <class T> static T create(); }; template < class lhs, class rhs > struct is_arrow_operable_impl { template <class T, class U, class = decltype(impl::create<T>()->impl::create<U>()) > void test(); }; I'm getting "internal compiler error: Segmentation fault" without further context information. Note that *this* example *can* lead to valid code when attempting to instantiate is_arrow_operable_impl with impl* and int, respectively, for example.