Automatic conversion of arguments in template functions

M

Meph

I know the following is supposed to work because struct AAA has a
constructor taking an int.

#include<iostream>

struct AAA {
AAA(int n): value(n) {}
int value;
};

bool operator==(const AAA& p, const AAA& q)
{
return p.value==q.value;
}

int main()
{
AAA x(1);
std::cout<<(1==x)<<std::endl;

return 0;
}


Can anyone tell me the part of the standard that disallows the
templated version of the above, like so:

#include<iostream>

template<class T>
struct AAA {
AAA(int n): value(n) {}
int value;
};

template<class T>
bool operator==(const AAA<T>& p, const AAA<T>& q)
{
return p.value==q.value;
}

int main()
{
AAA<int> x(1);
std::cout<<(1==x)<<std::endl;

return 0;
}

Why isn't a compiler required to convert 1==x to AAA<int>(1)==x, as in
the non-template case?

Thanks,

Meph
 
V

Victor Bazarov

Meph said:
I know the following is supposed to work because struct AAA has a
constructor taking an int.

#include<iostream>

struct AAA {
AAA(int n): value(n) {}
int value;
};

bool operator==(const AAA& p, const AAA& q)
{
return p.value==q.value;
}

int main()
{
AAA x(1);
std::cout<<(1==x)<<std::endl;

return 0;
}


Can anyone tell me the part of the standard that disallows the
templated version of the above, like so:

#include<iostream>

template<class T>
struct AAA {
AAA(int n): value(n) {}
int value;
};

template<class T>
bool operator==(const AAA<T>& p, const AAA<T>& q)
{
return p.value==q.value;
}

int main()
{
AAA<int> x(1);
std::cout<<(1==x)<<std::endl;

return 0;
}

Why isn't a compiler required to convert 1==x to AAA<int>(1)==x, as in
the non-template case?

Section 14 of the Standard deals with templates. IIRC 14.8 deals
with deducing template arguments from a function call (in your case
operator== is that function). In that clause the Standard says that
no conversions are considered (you'd have to read it to find the
exact spot where it says that). The reason is that with templates
the set of types fitting the conversion is unlimited. The compiler
cannot arbitrarily decide that 'AAA<int>' is the right one because
I can create another specialisation of 'AAA' that might be better
fit, for example if I have the operator==(int, AAA<mytype>) defined
for it.

V
 
B

Barry

Meph said:
int main()
{
AAA<int> x(1);
std::cout<<(1==x)<<std::endl;

return 0;
}

Why isn't a compiler required to convert 1==x to AAA<int>(1)==x, as in
the non-template case?
<std>
14.8.2.1/3
— If P is a class, and P has the form template-id, then A can be a
derived class of the deduced A. Likewise, if P is a pointer to a class
of the form template-id, A can be a pointer to a derived class pointed
to by the deduced A.

These alternatives are considered only if type deduction would otherwise
fail

</std>

the case of conversion from 1 to AAA<int> is not included here for type
deduction.
operator== <int>(1, x) compiles somehow supports this.
 

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,969
Messages
2,570,161
Members
46,708
Latest member
SherleneF1

Latest Threads

Top