Boost logo

Boost Users :

Subject: Re: [Boost-users] Can not compile a program that uses typeof package by gcc?
From: Peng Yu (pengyu.ut_at_[hidden])
Date: 2008-10-20 12:45:25


On Mon, Oct 20, 2008 at 11:38 AM, Steven Watanabe <watanabesj_at_[hidden]> 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;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net