Why don't conversion operators work with template classes?

Y

ymost

Hi all,
I've recently learned that conversion operators don't work with
template classes. I have tried looking for an explanation for this,
but did not find a satisfactory one. Consider the following situation:

// -------------------------------------------------------------------
template<typename T> struct A {};

template<typename T> struct B {
operator A<T>() {return A<T>();}
};

template<typename T> void func(A<T> a) {}

int main() {
B<int> b;
func(b); // <---- cannot deduce template argument
return 0;
}
// -------------------------------------------------------------------

Both MS VC and gcc fail to compile the marked line.
As far as I can see, there are no circumstances in which allowing this
implicit conversion will cause ambiguity, so why isn't it allowed?
Also: is there a workaround?
 
A

alfps

Hi all,
I've recently learned that conversion operators don't work with
template classes.

They do.

I have tried looking for an explanation for this,
but did not find a satisfactory one. Consider the following situation:

// -------------------------------------------------------------------
template<typename T> struct A {};

template<typename T> struct B {
  operator A<T>() {return A<T>();}

};

template<typename T> void func(A<T> a) {}

int main() {
  B<int> b;
  func(b);   //  <----  cannot deduce template argument
  return 0;}

Template matching does not consider conversions (however, base classes
are considered).


// -------------------------------------------------------------------

Both MS VC and gcc fail to compile the marked line.
As far as I can see, there are no circumstances in which allowing this
implicit conversion will cause ambiguity, so why isn't it allowed?
Also: is there a workaround?

Insofar as it's possible to talk about this problem as common, the
general solution is to employ inheritance (which is considered for
template matching) rather than a conversion, and provide a means for
the called routine to downcast.

However, instead of the general solution, which is complicated and
Difficult To Do Right, simply overload 'func'.

Cheers & hth.,

- Alf
 
Y

ymost

Template matching does not consider conversions (however, base classes
are considered).

I'm sorry if I phrased the title wrong, but that's what I meant (i.e.
that template matching does not consider conversions).
Insofar as it's possible to talk about this problem as common, the
general solution is to employ inheritance (which is considered for
template matching) rather than a conversion, and provide a means for
the called routine to downcast.

I know that inheritance can solve this problem, but in many situations
(including the one I am facing) choosing inheritance is the wrong
design decision (i.e. the classes don't have a "is a" relationship),
and can lead to many pitfalls.
However, instead of the general solution, which is complicated and
Difficult To Do Right, simply overload 'func'.

Overloading func can solve this too, but in my case I have not one,
but many functions, and overloading all of them is exactly what I am
trying to avoid. I guess I just can't avoid it, or can I?
 
G

Gerhard Fiedler

Overloading func can solve this too, but in my case I have not one,
but many functions, and overloading all of them is exactly what I am
trying to avoid. I guess I just can't avoid it, or can I?

You could provide a function or a few functions that accepts a pointer
to func and a B<T> as arguments, if that helps (and if your many
functions have the same or only a few distinct signatures).

Gerhard
 
B

Bertrand

Hi all,
I've recently learned that conversion operators don't work with
template classes. I have tried looking for an explanation for this,
but did not find a satisfactory one. Consider the following situation:

template<typename T> struct A {};

template<typename T> struct B {
operator A<T>() {return A<T>();}
};

template<typename T> void func(A<T> a) {}

int main() {
B<int> b;
func<int>(b); // solves the problem
return 0;
}
tested with g++ 4.3.2.

I think the problem is that func is a templated function, and before a
conversion operator for b might be considered, it has to be determined
what the function is... usually, for templated function, the type of the
arguments can help the compiler deciding which function the call
resolves to, but not here. a catch 22 situation!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,115
Latest member
JoshuaMoul
Top