
On Mon, Oct 20, 2008 at 11:14 AM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
Peng Yu wrote:
template <typename T1, typename T2> struct multiply_traits;
template <typename T1, typename T2> struct multiply_traits<X<T1>, T2> { typedef X<T1> result_type; };
The most reliable way to define multiply_traits in general is
template<class T> T make();
template<class T1, class T2> struct multiply_traits { BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, make<T1>() * make<T2>()); typedef typename nested::type type; };
Y<BOOST_TYPEOF(T1() * T2())> operator*(const Y<T1> &y, const T2 &t)
You need to use BOOST_TYPEOF_TPL. http://www.boost.org/doc/libs/1_36_0/doc/html/typeof/refe.html#typeof.typo. Some compilers can handle this (I just tried it on msvc 9.0), but I strongly advise using multiply_traits as defined above for portability.
I changed the code according to you message (see below this message). I got the following error, would you please help me figure out what was wrong? main.cc: In instantiation of 'A::multiply_traits<A::X<int>, int>::nested': main.cc:32: instantiated from 'A::multiply_traits<A::X<int>, int>' main.cc:65: instantiated from here main.cc:31: error: no match for 'operator*' in 'A::make [with T = A::X<int>]() * A::make [with T = int]()' main.cc: In function 'int main()': main.cc:65: error: no match for 'operator*' in 'x * 3' main.cc:66: error: no match for 'operator*' in 'A::X<int>() * 0' main.cc:66: error: no match for 'operator*' in 'y * 5' make: *** [main-g.o] Error 1 Thanks, Peng #include <boost/typeof/typeof.hpp> #include <iostream> namespace A { template <typename T> class X { public: X() { } X(T t) : _t(t) { } const T &the_t() const { return _t; } private: T _t; }; template <typename T1, typename T2> struct multiply_traits; #if 0 template <typename T1, typename T2> struct multiply_traits<X<T1>, T2> { typedef X<T1> result_type; }; #endif template<class T> T make(); template<class T1, class T2> struct multiply_traits { BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, make<T1>() * make<T2>()) typedef typename nested::type type; }; template <typename T1, typename T2> typename multiply_traits<X<T1>, T2>::result_type operator*(const X<T1> &x, const T2 &t) { return X<T1>(x.the_t() * t); } } namespace B { template <typename T> class Y { public: Y(T t) : _t(t) { } const T &the_t() const { return _t; } private: T _t; }; template <typename T1, typename T2> //Y<typename multiply_traits<T1, T2>::result_type> operator*(const Y<T1> &y, const T2 &t) { //Y<T1> operator*(const Y<T1> &y, const T2 &t) { Y<BOOST_TYPEOF_TPL(T1() * T2())> operator*(const Y<T1> &y, const T2 &t) { return Y<T1>(y.the_t() * t); } } int main () { A::X<int> x(2); B::Y<A::X<int> > y(x); std::cout << (x * 3).the_t() << std::endl; std::cout << (y * 5).the_t().the_t() << std::endl; }