why overloading isn't happened? | | |
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;
}
================================================== ============ | | | | 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 | | | | 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. | | | | 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 |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,471 network members.
|