Topic: Conversion constructors and template arguments.
Author: kruland@ku.edu (Kevin Ruland)
Date: Thu, 3 Feb 2005 04:58:08 GMT Raw View
Hi all.
I have a template class with conversion operator:
template< typename T >
class FooWrapper {
public:
FooWrapper( const T& rhs );
}
Along with some specializations for this:
template<>
class FooWrapper<MyType> {
public:
FooWrapper( const MyType& rhs );
}
and so forth.
Now I'm defining some operators using templates which I want to be
limited to only FooWrapper<T> classes.
template<typename T, typename U>
int
operator+ (const FooWrapper<T>&, const FooWrapper<T>& );
The problem I'm having is compiling code like this:
MyType a, b;
int i = a + b;
Under g++ 3.2.3.20030502 it states there is no operator+ for MyType&,
MyType&.
Really, my question is why are the user defined conversions not
considered when trying to match with the customer operator+?
Thanks much.
Kevin Ruland
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: gprenz@hotmail.com (Graeme Prentice)
Date: Thu, 10 Feb 2005 17:16:17 GMT Raw View
On Thu, 3 Feb 2005 04:58:08 GMT, Kevin Ruland wrote:
>
>
>Hi all.
>
>I have a template class with conversion operator:
>
>template< typename T >
>class FooWrapper {
>public:
> FooWrapper( const T& rhs );
>}
>
>Along with some specializations for this:
>
>template<>
>class FooWrapper<MyType> {
>public:
> FooWrapper( const MyType& rhs );
>}
>
>and so forth.
>
>Now I'm defining some operators using templates which I want to be
>limited to only FooWrapper<T> classes.
>
>template<typename T, typename U>
>int
>operator+ (const FooWrapper<T>&, const FooWrapper<T>& );
>
>
>The problem I'm having is compiling code like this:
>
>MyType a, b;
>int i = a + b;
>
>Under g++ 3.2.3.20030502 it states there is no operator+ for MyType&,
>MyType&.
>
>Really, my question is why are the user defined conversions not
>considered when trying to match with the customer operator+?
>
For the same reason this code won't compile
template<typename T >
void f1( const FooWrapper<T>& );
int main() { f1(a); }
a has type MyType. Argument deduction requires that the deduced
function parameter type ( const FooWrapper<T>& ) exactly match the
argument type (MyType) -
<quote 14.8.2.1/3>
In general, the deduction process attempts to find template argument
values that will make the deduced A identical to A (after the type A is
transformed as described above). However, there are three cases that
allow a difference:
<>
The allowed differences are to do with const (c/v) conversion and
derived to base conversion for a template-id - user defined conversions
are not allowed for parameters that are involved in argument deduction.
If the user defined conversion was allowed, the operator+ would become a
candidate for all types - which is a bit too "all encompassing" and
"interferes" with operator+ operations on all types.
You could think about using an in class friend function definition like
this
template< typename T >
class FooWrapper {
public:
FooWrapper( const T& rhs );
friend int operator+(const T& a, const T& b)
{
return operator+(FooWrapper<T>(a), FooWrapper<T>(b));
}
};
but you have to instantiate the FooWrapper<T> class first and this works
with GCC but not with Comeau or VC7.1 so this isn't really viable. I'm
not sure how name lookup is supposed to work here but you can see some
comments I made about this issue a while ago
http://makeashorterlink.com/?P20012D6A
You could use an obscure technique that saves a small amount of typing
struct MyType2 { typedef int FooWrapperTOperatorPlusReturnType; };
template <typename T>
typename T::FooWrapperTOperatorPlusReturnType
operator+(const T&, const T&);
MyType2 x,y;
int j = x + y;
but I think it best to define all the operator+ explicitly unless all
the classes involved inherit from a common base class for other reasons.
Graeme
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]