
On Mon, Oct 20, 2008 at 11:38 AM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
Peng Yu wrote:
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
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); }
}
Note that the operator* deduces it's return type from multiply_traits, and multiply_traits in turn uses the result of operator*. You need to either specialize multiply_traits for X. (The specialization you #if'ed out should work fine). Or you can change operator*:
template<class T1, class T2> X<T1> operator*(const X<T1> &x, const T2 &t);
Also, I made a mistake, multiply_traits should say typedef typedef nested::type result_type; instead of typedef ... type;.
I'm not sure if I understand you correctly. But I got the following code which still ends up with the compiler bug. Would you please give me a complete working copy of the program so that I can play with it? 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; template <typename T1, typename T2> struct multiply_traits<X<T1>, T2> { typedef X<T1> result_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); } 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; }; } 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; }