Template Arguments Deduction Context?

C

coolpint

Can anyone kindly provide an explanation as to why the compiler does
not "see" the function template in the contrieved code below?

I think the argument deduction fails but can't figure out exactly what
the problem is. Is it related to the fact that a nested class is
involved?

#include <iostream>
using std::cout;

template <typename T>
class MyClass {
public:
class InnerClass;
};

template <typename T>
bool operator==(const typename MyClass<T>::InnerClass &a ,
const typename MyClass<T>::InnerClass & b)
{ return a.value == b.value; }

template <typename T>
class MyClass<T>::InnerClass {
friend bool operator==<T>(const MyClass<T>::InnerClass &,
const
MyClass<T>::InnerClass &);
public:
InnerClass(T x):value(x) { }
private:
T value;
};

int main()
{
MyClass<int>::InnerClass x(10), y(10);
if (x == y)
cout << "YES";
else
cout << "NO";
}

I am implementing a generic Container; Its Iterators are defiend as
public nested classes.
To test equality between Read-Only Iterators and Read-Write Iterators,
I wrote a namespace operator overloaded function accepting two
Read-Only Iterators and had a conversion constructor to implicitly
convert Read-Write Iterator to Read-Only Iterator.

But then I am facing the problem similar to the one depicted above
where the compiler fails to instantiate the necessary operator
overloaded function. My search for the clue on the Internet led me to
something called "deduced contexts" and it seems like the compiler does
not deduce a template parameter, T, for a type name like
Container<T>::ROIterator.

If that's the case, what are possible solutions to the problem like
this?

Does it mean I cannot have Iterators as nested classes? I like this
organization since the Iterators are logically bound to the Container,
in my humble opinion.

Or am I forced to implement numerous versions of the operator==
function as member functions?

Or should I 'define' the operator function in the ROIterator class
template as a normal friend fuction? (Is it something called
Barton-Nackman trick?)

I would like to know what expert programmers do in a situation like
this and learn from your kind advice and suggestions. Thank you in
advance for any help and explanations.


Another related question is whether it's necessary to provide complete
definition of a class template before its member function is made a
friend of another class. I understand that for normal (non-template)
classes, the compiler must 'see' complete definition of the class
before its member functions can be declared friend of another class.

Does this rule applies to class templates, too? The reason I am asking
is because my compiler didn't complain at all and I just realized I
made a mistake of only providing forward declaration of the class
template when making one of its member functions a friend of another
class templalate.
Thanks again for your help one more time.
 
G

Gianni Mariani

Can anyone kindly provide an explanation as to why the compiler does
not "see" the function template in the contrieved code below?
....

template <typename T>
bool operator==(const typename MyClass<T>::InnerClass &a ,
const typename MyClass<T>::InnerClass & b)
{ return a.value == b.value; }

Check out this thread.

http://groups.google.com/group/comp...ce581/efb451eae2fc7c39?hl=en#efb451eae2fc7c39

Basically, the compiler can't deduce when referencing inner components
of the class.
 
G

Greg

Can anyone kindly provide an explanation as to why the compiler does
not "see" the function template in the contrieved code below?

I think the argument deduction fails but can't figure out exactly what
the problem is. Is it related to the fact that a nested class is
involved?

#include <iostream>
using std::cout;

template <typename T>
class MyClass {
public:
class InnerClass;
};

template <typename T>
bool operator==(const typename MyClass<T>::InnerClass &a ,
const typename MyClass<T>::InnerClass & b)
{ return a.value == b.value; }

template <typename T>
class MyClass<T>::InnerClass {
friend bool operator==<T>(const MyClass<T>::InnerClass &,
const
MyClass<T>::InnerClass &);
public:
InnerClass(T x):value(x) { }
private:
T value;
};

int main()
{
MyClass<int>::InnerClass x(10), y(10);
if (x == y)
cout << "YES";
else
cout << "NO";
}

I am implementing a generic Container; Its Iterators are defiend as
public nested classes.
To test equality between Read-Only Iterators and Read-Write Iterators,
I wrote a namespace operator overloaded function accepting two
Read-Only Iterators and had a conversion constructor to implicitly
convert Read-Write Iterator to Read-Only Iterator.

But then I am facing the problem similar to the one depicted above
where the compiler fails to instantiate the necessary operator
overloaded function. My search for the clue on the Internet led me to
something called "deduced contexts" and it seems like the compiler does
not deduce a template parameter, T, for a type name like
Container<T>::ROIterator.

If that's the case, what are possible solutions to the problem like
this?

How about an implementation along these lines:

#include <iostream>
using std::cout;

template <typename T>
class MyClass
{
public:
class InnerClass
{
public:
InnerClass(T x): value(x) { }

bool operator==(const InnerClass& rhs)
{
return a.value == b.value;
}

private:
T value;
};
};

int main()
{
MyClass<int>::InnerClass x(10), y(10);
if (x == y)
cout << "YES";
else
cout << "NO";
}

Output:
YES

Greg
 

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,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top