Hi,

I was porting session_services.cc to posix today, and I ran across a
g++ bug that will definitely block efforts to use CancelableRequest,
at least on Linux.  While I'm savvy enough with C++, I'm having
trouble coming up with an explanation for what the problem is here.
I'd like to file a bug with gcc, but I don't want to just toss this
file on their laps.  Can someone take a look at the test case I've
attached and see if they can shed some light?  btw this test case
compiles successfully in visual studio.

$ g++ testcase.cc
testcase.cc: In constructor
'InternalGetCommandsRequest::InternalGetCommandsRequest(CallbackRunner<Tuple2<int,
InternalGetCommandsRequest> >*)':
testcase.cc:89: error: class 'InternalGetCommandsRequest' does not
have any field named 'CancelableRequest'
testcase.cc:89: error: no matching function for call to
'CancelableRequest<CallbackRunner<Tuple2<int,
InternalGetCommandsRequest> > >::CancelableRequest()'
testcase.cc:21: note: candidates are:
CancelableRequest<CB>::CancelableRequest(CB*) [with CB =
CallbackRunner<Tuple2<int, InternalGetCommandsRequest> >]
testcase.cc:13: note:
CancelableRequest<CallbackRunner<Tuple2<int,
InternalGetCommandsRequest> > >::CancelableRequest(const
CancelableRequest<CallbackRunner<Tuple2<int,
InternalGetCommandsRequest> > >&)

It seems that the critical point is:

no matching function for call to
'CancelableRequest<CallbackRunner<Tuple2<int,
InternalGetCommandsRequest> > >::CancelableRequest()'

when the code in question is:

explicit InternalGetCommandsRequest(CallbackType* callback) :
CancelableRequest(callback) { }

For some reason, g++ is not picking up that we are passing a var of
type CallbackType* which fully translates to:

const CancelableRequest<CallbackRunner<Tuple2<int,
InternalGetCommandsRequest> > >&

which would match the expected:

CancelableRequest<CallbackRunner<Tuple2<int,
InternalGetCommandsRequest> > >::CancelableRequest(const
CancelableRequest<CallbackRunner<Tuple2<int,
InternalGetCommandsRequest> > >&)


Thanks,
James Hawkins

--~--~---------~--~----~------------~-------~--~----~
Chromium Developers mailing list: [email protected] 
View archives, change email options, or unsubscribe: 
    http://groups.google.com/group/chromium-dev
-~----------~----~----~----~------~----~------~--~---

class CancelableRequestBase {
 public:
  friend class CancelableRequestProvider;

  CancelableRequestBase() {

  }
  virtual ~CancelableRequestBase() {
  }
};

template<typename CB>
class CancelableRequest : public CancelableRequestBase {
 public:
  typedef CB CallbackType;          // CallbackRunner<...>
  typedef typename CB::TupleType TupleType;  // Tuple of the callback args.

  // The provider MUST call Init() (on the base class) before this is valid.
  // This class will take ownership of the callback object and destroy it when
  // appropriate.
  explicit CancelableRequest(CallbackType* callback)
      : CancelableRequestBase(),
        callback_(callback) {

  }
  virtual ~CancelableRequest() {
  }

 private:
  CallbackType* callback_;
};

template <class P>
struct TupleTraits {
  typedef P ValueType;
  typedef P& RefType;
  typedef const P& ParamType;
};

template <class P>
struct TupleTraits<P&> {
  typedef P ValueType;
  typedef P& RefType;
  typedef P& ParamType;
};

template <class A, class B>
struct Tuple2 {
 public:
  typedef A TypeA;
  typedef B TypeB;
  typedef Tuple2<typename TupleTraits<A>::ValueType,
                 typename TupleTraits<B>::ValueType> ValueTuple;
  typedef Tuple2<typename TupleTraits<A>::RefType,
                 typename TupleTraits<B>::RefType> RefTuple;

  Tuple2() {}
  Tuple2(typename TupleTraits<A>::ParamType a,
         typename TupleTraits<B>::ParamType b)
      : a(a), b(b) {
  }

  A a;
  B b;
};

template <typename Params>
class CallbackRunner {
 public:
  typedef Params TupleType;

  virtual ~CallbackRunner() {}
  virtual void RunWithParams(const Params& params);

};

// 2-arg implementation
template <typename Arg1, typename Arg2>
struct Callback2 {
  typedef CallbackRunner<Tuple2<Arg1, Arg2> > Type;
};

class InternalGetCommandsRequest;
  typedef Callback2<int, InternalGetCommandsRequest>::Type
      InternalGetCommandsCallback;
  class InternalGetCommandsRequest :
      public CancelableRequest<InternalGetCommandsCallback> {
   public:
    explicit InternalGetCommandsRequest(CallbackType* callback) : CancelableRequest(callback) {
    }
    virtual ~InternalGetCommandsRequest();
  };

int main(void)
{

  return 0;
}

Reply via email to