Implicit type conversion in combination with templates

T

tonvandenheuvel

Hi all,

please consider the following piece of code:

#include <iostream>

template<typename T>
class A
{
public:
A(T t) { prop = t; };
bool operator!=(A<T> a) { return prop != a.prop; }

protected:
A() { };

T prop;
};

class B : public A<int>
{
public:
B(int i): A<int>(i) { };
};

class C : public A<double>
{
public:
C(double d): A<double>(d) { };
C(B b): A<double>(0) { };
};

int main(void)
{
B b(4);
C c(3);
if (c != b)
std::cout << "not equal" << std::endl;
else
std::cout << "equal" << std::endl;
}

I would expect b to be implicitly converted to an instance of C, such
that the != operator can be properly called. Instead, gcc complains as
follows:

implicit.cpp: In function 'int main()':
implicit.cpp:33: error: no match for 'operator!=' in 'c != b'
implicit.cpp:8: note: candidates are: bool A<T>::eek:perator!=(A<T>)
[with T = double]

(tried with gcc 4.0.x & 4.1.x)

Any ideas why this fails? In case A is not templated, everything
compiles just fine.

Cheers,
Ton
 
V

Victor Bazarov

please consider the following piece of code:

#include <iostream>

template<typename T>
class A
{
public:
A(T t) { prop = t; };

Please drop the trailing semicolons after function bodies and use
initialiser list instead of assignment:

A(T t) : prop(t) {}
bool operator!=(A<T> a) { return prop != a.prop; }
protected:
A() { };

T prop;
};

class B : public A<int>
{
public:
B(int i): A<int>(i) { };
};

class C : public A<double>
{
public:
C(double d): A<double>(d) { };
C(B b): A<double>(0) { };
};

int main(void)
{
B b(4);
C c(3);
if (c != b)
std::cout << "not equal" << std::endl;
else
std::cout << "equal" << std::endl;
}

I would expect b to be implicitly converted to an instance of C, such
that the != operator can be properly called.

In order to do that, it has to figure out which operator to call. It
sees

A<double> operator != (A<double>)

that exists in 'C'. Now, once it figured the function the conversions
are considered. Is there a conversion from B to A said:
Instead, gcc complains as
follows:

implicit.cpp: In function 'int main()':
implicit.cpp:33: error: no match for 'operator!=' in 'c != b'
implicit.cpp:8: note: candidates are: bool A<T>::eek:perator!=(A<T>)
[with T = double]

(tried with gcc 4.0.x & 4.1.x)

Any ideas why this fails? In case A is not templated, everything
compiles just fine.

V
 
A

A.W. van den Heuvel

Please drop the trailing semicolons after function bodies and use
initialiser list instead of assignment:

A(T t) : prop(t) {}

This is of course a quick and dirty example, sorry for the mess.
In order to do that, it has to figure out which operator to call. It
sees

A<double> operator != (A<double>)

that exists in 'C'. Now, once it figured the function the conversions
are considered. Is there a conversion from B to A<double>?

I agree there is no direct conversion possible, but a conversion from
B to C is possible, and then a conversion from C to A<double> is
possible. IIRC, implicit conversion via at most two user defined types
should be supported by the compiler?
Instead, gcc complains as
follows:
implicit.cpp: In function 'int main()':
implicit.cpp:33: error: no match for 'operator!=' in 'c != b'
implicit.cpp:8: note: candidates are: bool A<T>::eek:perator!=(A<T>)
[with T = double]
(tried with gcc 4.0.x & 4.1.x)
Any ideas why this fails? In case A is not templated, everything
compiles just fine.

V
 

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,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top