#include #include namespace A { template class X { public: X() { } X(T t) : _t(t) { } const T &the_t() const { return _t; } private: T _t; }; template struct multiply_traits; template struct multiply_traits, T2> { typedef X result_type; }; template typename multiply_traits, T2>::result_type operator*(const X &x, const T2 &t) { return X(x.the_t() * t); } template T make(); template struct multiply_traits { BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, make() * make()) typedef typename nested::type type; }; } namespace B { template class Y { public: Y(T t) : _t(t) { } const T &the_t() const { return _t; } private: T _t; }; template Y::result_type> operator*(const Y &y, const T2 &t) { return Y(y.the_t() * t); } } int main () { A::X x(2); B::Y > y(x); std::cout << (x * 3).the_t() << std::endl; std::cout << (y * 5).the_t().the_t() << std::endl; }