Connecting Tech Pros Worldwide Forums | Help | Site Map

why overloading isn't happened?

胡岳偉(Yueh-Wei Hu)
Guest
 
Posts: n/a
#1: Jul 22 '05
Hi all,

I have 2 questions about template function as friends in template
classes. I don't know why, and hope someone could help me.

================================================== ============
Question 1:
================================================== ============

Compile the following codes, and run it.
The program will print

"T<a, b>"

on the screen.

However, I consider that "T<a, 3>" should be displayed.

Why this program print "T<a, b>"?

My building environment is:

1) gcc-3.3
2) linux kernel 2.6.6

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

#include <iostream>

template<int a, int b>
class T;

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

template<int a, int b>
class T
{
private:

int c;

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)
{
t->c = 2;
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;
}

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

I add another function template:

friend void func<b>(T<3, b> const * const t);

and define it, too.

However, when I compile this program, gcc shows the following error
message:

eee.cpp: In instantiation of `T<2, 3>':
eee.cpp:50: instantiated from here
eee.cpp:19: error: ambiguous template specialization `func<3>' for
`void
func(const T<3, 3>*)'

What does the 'ambiguous template specialization' indicate?
I can't figure it out.

Thank you for your help.

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

#include <iostream>

template<int a, int b>
class T;

template<int a, int b>
void func(T<a, b> const * const t)
{
t->c = 3;
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 line -->

public:

void ttt() const;
};

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

template<int b> <-- add definition -->
void
func(T<3, b> const * const t)
{
t->c = 1;
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;
}

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

Victor Bazarov
Guest
 
Posts: n/a
#2: Jul 22 '05

re: why overloading isn't happened?


Yueh-Wei Hu wrote:[color=blue]
> I have 2 questions about template function as friends in template
> classes. I don't know why, and hope someone could help me.
>
> ================================================== ============
> Question 1:
> ================================================== ============
>
> Compile the following codes, and run it.[/color]

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>
[color=blue]
> The program will print
>
> "T<a, b>"
>
> on the screen.
>
> However, I consider that "T<a, 3>" should be displayed.[/color]

When the program is corrected, yes.
[color=blue]
>
> Why this program print "T<a, b>"?[/color]

Because you have a buggy compiler, probably...
[color=blue]
>
> My building environment is:
>
> 1) gcc-3.3
> 2) linux kernel 2.6.6[/color]

Fall back on gcc-3.2
[color=blue]
>
> ================================================== ============
>
> #include <iostream>
>
> template<int a, int b>
> class T;
>
> template<int a, int b>
> void func(T<a, b> const * const t)
> {
> t->c = 3;[/color]

'*t' is const here. Friendship doesn't change that. Comment it out.
[color=blue]
> std::cerr << "T<a, b>" << std::endl;
> }
>
> template<int a, int b>
> class T
> {
> private:
>
> int c;
>
> 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)
> {
> t->c = 2;[/color]

Again, '*t' is a const object. Comment this out too.
[color=blue]
> 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;
> }[/color]

After commenting out the offending lines, the code compiles fine (as it
should).
[color=blue]
>
> ================================================== ===========
> Question 2:
> ================================================== ===========
>
> I add another function template:
>
> friend void func<b>(T<3, b> const * const t);
>
> and define it, too.
>
> However, when I compile this program, gcc shows the following error
> message:
>
> eee.cpp: In instantiation of `T<2, 3>':
> eee.cpp:50: instantiated from here
> eee.cpp:19: error: ambiguous template specialization `func<3>' for
> `void
> func(const T<3, 3>*)'
>
> What does the 'ambiguous template specialization' indicate?
> I can't figure it out.[/color]

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>
[color=blue]
> Thank you for your help.
> [...][/color]

Victor
胡岳偉(Yueh-Wei Hu)
Guest
 
Posts: n/a
#3: Jul 22 '05

re: why overloading isn't happened?


Victor Bazarov <v.Abazarov@comAcast.net> wrote in message news:<AGrrc.377$ri.43449@dfw-read.news.verio.net>...
================================================== ============[color=blue][color=green]
> > Question 1:
> > ================================================== ============[/color][/color]
[color=blue]
> 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>
>[/color]

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.
[color=blue]
> Fall back on gcc-3.2[/color]

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?

================================================== ===========[color=blue][color=green]
> > Question 2:
> > ================================================== ===========[/color][/color]
[color=blue]
>
> 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[/color]

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.
Victor Bazarov
Guest
 
Posts: n/a
#4: Jul 22 '05

re: why overloading isn't happened?


Yueh-Wei Hu <ywhu@iii.org.tw> wrote...[color=blue]
> Victor Bazarov <v.Abazarov@comAcast.net> wrote in message[/color]
news:<AGrrc.377$ri.43449@dfw-read.news.verio.net>...[color=blue]
> ================================================== ============[color=green][color=darkred]
> > > Question 1:
> > > ================================================== ============[/color][/color]
>[color=green]
> > 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>
> >[/color]
>
> 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.
>[color=green]
> > Fall back on gcc-3.2[/color]
>
> I fall back to gcc-3.2, and I can _not_ compile it !
>
> The error message from gcc-3.2 is as following:
> [...]
>
> I can not figure it out why overload doesn't appear.
> Could somebody explain this?[/color]

You need to talk to people in a gnu newsgroup. Apparently gcc is
still behind on the standard compliancy. The explanation is simple:
the compiler is not up to par. The solution is simpler: use another
[better] compiler. If you can't, you're screwed until they manage
to fix it.

Victor


Closed Thread


Similar C / C++ bytes