Listing 1: Unconsting and unrefing with trace
template<typename U> class NONCONST { public: typedef U RET; static void trace() { std::cout << "Default NONCONST<U>" << std::endl; } }; template<typename U> class NONCONST<const U> { public: typedef U RET; static void trace() { std::cout << "NONCONST<const U>" << std::endl; } }; template<typename U> class NONREF { public: typedef U RET; static void trace() { std::cout << "Default NONREF<U>" << std::endl; } }; template<typename U> class NONREF<U&> { public: typedef U RET; static void trace() { std::cout << "NONREF<U&>" << std::endl; } }; template<typename Func> class X { typedef Func::first_argument_type first_arg; typedef NONCONST<NONREF<first_arg>::RET>::RET raw_first_arg; public: X( const raw_first_arg & theFirstArg) : m_theFirstArg(theFirstArg) { NONREF<first_arg>::trace(); NONCONST<NONREF<first_arg>::RET>::trace(); std::cout << std::endl; } private: raw_first_arg m_theFirstArg; }; class func1 { typedef int first_argument_type; }; class func2 { typedef const int first_argument_type; }; class func3 { typedef int& first_argument_type; }; class func4 { typedef const int& first_argument_type; }; int main() { int arg = 42; X<func1> x1(arg); X<func2> x2(arg); X<func3> x3(arg); X<func4> x4(arg); return 0; } End of Listing