Re: why overloading isn't happened? (using friend function template in class template)

From: 胡岳偉(Yueh-Wei Hu) (ywhu_at_iii.org.tw)
Date: 05/22/04


Date: 21 May 2004 21:31:10 -0700

Victor Bazarov <v.Abazarov@comAcast.net> wrote in message news:<AGrrc.377$ri.43449@dfw-read.news.verio.net>...
==============================================================
> > Question 1:
> > ==============================================================

> Your code refuses to compile. In function 'foo<a>' 't' is a pointer to
> const. Friendship has nothing to do with it. When I remove the attempt
> to change 't->c' in foo<a>, it compiles and runs and displays
>
> T<a, 3>
>

This is my fault, sorry.

The 't->c' assignment is added by me after I copied and pasted the
source codes to the news.

The reason why I did this is to emphasize the need of 'friend'
declarations.

> Fall back on gcc-3.2

I fall back to gcc-3.2, and I can _not_ compile it !

The error message from gcc-3.2 is as following:

==============================================================

eee.cpp: In member function `void T<a, b>::ttt() const [with int a =
2, int b =
   3]':
eee.cpp:52: instantiated from here
eee.cpp:44: call of overloaded `func(const T<2, 3>* const)' is
ambiguous
eee.cpp:8: candidates are: void func(const T<a, b>*) [with int a = 2,
int b =
   3]
eee.cpp:29: void func(const T<a, 3>*) [with int a = 2]
eee.cpp:8: void func(const T<a, b>*) [with int a = 2,
int b =
   3]
eee.cpp:29: void func(const T<a, 3>*) [with int a = 2]

==============================================================

The source code is as following:

==============================================================

#include <iostream>

template<int a, int b>
class T;

template<int a, int b>
void func(T<a, b> const * const t)
{
  std::cerr << "T<a, b>" << std::endl;
}

template<int a, int b>
class T
{
private:
  
  friend void func<a, b>(T<a, b> const * const t);
  friend void func<a>(T<a, 3> const * const t);
  
public:
  
  void ttt() const;
};

template<int a>
void
func(T<a, 3> const * const t)
{
  std::cerr << "T<a, 3>" << std::endl;
}

template<int a, int b>
void
T<a, b>::ttt() const
{
  func(this);
}

int
main()
{
  T<2, 3> t;
  
  t.ttt();
  
  return 0;
}

==============================================================

However, when I use gcc-3.2, gcc-3.3, gcc-3.4 to compile my code, the
result is strange.

Here is my result:

1) gcc-3.2: can _not_ compile, the error message is copied and pasted
above.

2) gcc-3.3: can compile, but the result is

T<a, b>

3) gcc-3.4: can compile, but the result is

T<a, b>

So....
What behavior conforms to the C++ standard?
And which version of gcc is correct?

=============================================================
> > Question 2:
> > =============================================================

>
> Neither can I. The code compiles file once the offending lines that
> attemp to change 't->c' are commented out and the resulting program outputs
>
> T<a, 3>
>
>
> Victor

I can _not_ compile the code using gcc-3.2, and the error message is
like the one I posted above:

==============================================================

eee.cpp: In instantiation of `T<2, 3>':
eee.cpp:50: instantiated from here
eee.cpp:19: ambiguous template specialization `func<3>' for `void
func(const
   T<3, 3>*)'
eee.cpp: In member function `void T<a, b>::ttt() const [with int a =
2, int b =
   3]':
eee.cpp:52: instantiated from here
eee.cpp:44: call of overloaded `func(const T<2, 3>* const)' is
ambiguous
eee.cpp:8: candidates are: void func(const T<a, b>*) [with int a = 2,
int b =
   3]
eee.cpp:29: void func(const T<a, 3>*) [with int a = 2]
eee.cpp:8: void func(const T<a, b>*) [with int a = 2,
int b =
   3]
eee.cpp:29: void func(const T<a, 3>*) [with int a = 2]

==============================================================

The source code I use is as following:

==============================================================

#include <iostream>

template<int a, int b>
class T;

template<int a, int b>
void func(T<a, b> const * const t)
{
  std::cerr << "T<a, b>" << std::endl;
}

template<int a, int b>
class T
{
private:
  
  friend void func<a, b>(T<a, b> const * const t);
  friend void func<a>(T<a, 3> const * const t);
  friend void func<b>(T<3, b> const * const t); <-- add this -->
  
public:
  
  void ttt() const;
};

template<int a>
void
func(T<a, 3> const * const t)
{
  std::cerr << "T<a, 3>" << std::endl;
}

template<int b> <-- add this definition -->
void
func(T<3, b> const * const t)
{
  std::cerr << "T<3, b>" << std::endl;
}

template<int a, int b>
void
T<a, b>::ttt() const
{
  func(this);
}

int
main()
{
  T<2, 3> t;
  
  t.ttt();
  
  return 0;
}

==============================================================

Again, the following is the result when I compile it using gcc-3.2,
gcc-3.3 and gcc-3.4:

1) gcc-3.2: can _not_ compile, the error message posted above.
2) gcc-3.3: can _not_ compile, the error message just like the one
posted for gcc-3.2.
3) gcc-3.4: can compile, but the result is

T<a, b>

==============================================================

I can not figure it out why overload doesn't appear.
Could somebody explain this?

Thank you for you help.



Relevant Pages