Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit conversion to a C++ template object

Tags:

c++

I have a class A:

template <typename T, int I> struct A {};

and a class B. I would like object's of type B to implicitly convert to A when given as function arguments. B looks like this:

template <typename T>
struct B {
  operator A<T,0> &() const { return *new A<T,0>(); }
};

However, my test (below) fails with GCC 4.5, giving the error: no matching function for call to 'test(B&)' Where am I going wrong here? Do other compilers also reject this?

template <typename T, int I>
void test(A<T,I> &a) { delete &a; }

int main(int argc, char *argv[])
{
  B<int> b;
  test(b);
  return 0;
}

p.s. I've now put my own solution in an answer below.

like image 352
user2023370 Avatar asked Mar 28 '11 16:03

user2023370


2 Answers

Unrelated to your problem but return *new A<T,0>(); is wrong since it leaks memoryinvites a memory leak. You should not use new here. return A<T, 0>(); and removing the reference from the return type works just fine and does not leak memory.

like image 134
Konrad Rudolph Avatar answered Oct 21 '22 03:10

Konrad Rudolph


If you want an implicit conversion from B to A you would need either:

A cast operator on B:

operator A<T,0>();

or an A constructor which takes a B reference:

A( const B& other );

or for B to derive from A. What you have declared:

operator A<T,0> &() const;

looks a bit like an ill-declared address-of overload.

However, since test() takes a reference (and non-const at that), the casting operator option won't work.

This is what I've tested:

template <typename T, int I> struct A {};

template <typename T>
struct B {
  //operator A<T,0> &() const { return *new A<T,0>(); }

    template< int I >
    operator A<T, I> () const { return A< T, 0 >(); }
};

template <typename T, int I>
void test(A<T,I> &) { }

int f()
{
  B<int> b;

  A<int, 0> a( b );
  test(a); // <-- Success

  test(b); // <-- Failure, "could not deduce template argument"
  return 0;
}

Conversion to A by initialising a local variable works fine.

like image 34
RobH Avatar answered Oct 21 '22 03:10

RobH