Topic: function template resolution
Author: "T.Yoshida" <yoshida_t@giw.khi.co.jp>
Date: 1999/02/10 Raw View
Given the following two function templates:
template < class T1, class T2 > int f( T2 ); // #1
template < class T2 > int f( T2 ); // #2
how the function call below is to be resolved?
f<float>( 1.0F );
(1) f<float,float>(float)
(2) f<float>(float)
(3) Ambiguous
I feel it should resolve to (2) since it does not require template argument
deduction and I feel the resolution which does not require template argument
deduction should have precedence over the one which requires the deduction.
But I can not find such a precedence rule in the standard document.
At best, I think it should be flagged as error because of the ambiguity.
Still, a certain C++ compiler in the market resolves it to (1).
Can someone explain which is correct in the light of the C++ standard with
good rationale?
-----------------------------------------------------------------
Tsutomu Yoshida
Minokamo, Japan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Alex Vinokur <alexander.vinokur@telrad.co.il>
Date: 1999/02/11 Raw View
In article <79qv2d$6it$1@ns2.kow.khi.co.jp>,
"T.Yoshida" <yoshida_t@giw.khi.co.jp> wrote:
> Given the following two function templates:
>
> template < class T1, class T2 > int f( T2 ); // #1
> template < class T2 > int f( T2 ); // #2
>
> how the function call below is to be resolved?
>
> f<float>( 1.0F );
>
> (1) f<float,float>(float)
>
> (2) f<float>(float)
>
> (3) Ambiguous
[snip]
Hi,
There is a difference between
A.1) syntax of template (usual) function without arguments
A.2) syntax of template (usual) function with some (not all) arguments
A.3) syntax of template (usual) function with all arguments
B.1) syntax of template member function without arguments
B.2) syntax of template member function with some (not all) arguments
B.3) syntax of template member function with all arguments
This difference is demonstrated in the following example.
Alex
###################################################
############# 1. jp_class.H #######################
###################################################
#include <string>
//############################################
// template (usual) function without arguments
template <typename T1, typename T2>
void foo_no()
{
cout << __PRETTY_FUNCTION__ << " \t: No input parameters" << endl;
// __PRETTY_FUNCTION__ is predefined string variable in gcc/g++
}
//############################################
// template (usual) function only with first argument
template <typename T1, typename T2>
void foo_1(T1 &first)
{
cout << __PRETTY_FUNCTION__ << " \t: arg1 = " << first << endl;
}
//############################################
// template (usual) function only with second argument
template <typename T1, typename T2>
void foo_2(T2 &second)
{
cout << __PRETTY_FUNCTION__ << " \t: arg2 = " << second << endl;
}
//############################################ // template (usual) function
with all arguments template <typename T1, typename T2> void foo_all(T1
&first, T2 &second) { cout << __PRETTY_FUNCTION__ << " \t: arg1 = " << first
<< ", arg2 = " << second << endl; }
//############################################
class MyClass
{
public:
MyClass () {}
~MyClass () {}
//------------------------------------------
// template member function without arguments
template <typename T1, typename T2>
void Foo_no();
//------------------------------------------
// template member function only with first argument
template <typename T1, typename T2>
void Foo_1(T1 &first);
//------------------------------------------
// template member function only with second argument
template <typename T1, typename T2>
void Foo_2(T2 &second);
//------------------------------------------
// template member function only with all arguments
template <typename T1, typename T2>
void Foo_all(T1 &first, T2 &second);
};
//############################################
// template member function without arguments
template <typename T1, typename T2>
void MyClass::Foo_no()
{
cout << __PRETTY_FUNCTION__ << " \t: No input parameters" << endl;
}
//############################################
// template member function only with first argument
template <typename T1, typename T2>
void MyClass::Foo_1(T1 &first)
{
cout << __PRETTY_FUNCTION__ << " \t: Arg1 = " << first << endl;
}
//############################################
// template member function only with second argument
template <typename T1, typename T2>
void MyClass::Foo_2(T2 &second)
{
cout << __PRETTY_FUNCTION__ << " \t: Arg2 = " << second << endl;
}
//############################################ // template member function
with all arguments template <typename T1, typename T2> void
MyClass::Foo_all(T1 &first, T2 &second) { cout << __PRETTY_FUNCTION__ << "
\t: Arg1 = " << first << ", Arg2 = " << second << endl; }
###################################################
############# 2. MyClass.cpp ######################
###################################################
#include "jp_class.H"
// The file has no implementation (in this example)
###################################################
############# 3. jp_main.C ########################
###################################################
#include "jp_class.H"
int main ()
{
MyClass object;
int i11 = 11;
int i12 = 12;
int i21 = 21;
int i22 = 22;
int i31 = 31;
int i32 = 32;
int i41 = 41;
int i42 = 42;
char* c11 = "one_aaaaa";
char* c12 = "one_bbbbb";
char* c21 = "two_aaaaa";
char* c22 = "two_bbbbb";
char* c31 = "three_aaaaa";
char* c32 = "three_bbbbb";
char* c41 = "four_aaaaa";
char* c42 = "four_bbbbb";
//##############################################
//##############################################
cout << endl;
cout << endl;
cout << "###### foo_no : template (usual) function without arguments
######" << endl;
cout << " All template types are explicit" << endl;
foo_no<int, int> ();
foo_no<int, char*> ();
foo_no<char*, int> ();
foo_no<char*, char*> ();
//==============================================
cout << endl;
cout << endl;
cout << "###### foo_1 : template (usual) function only with first
argument ######" << endl;
cout << " All template types are explicit" << endl;
foo_1<int, int> (i11);
foo_1<int, char*> (i21);
foo_1<char*, int> (c31);
foo_1<char*, char*> (c41);
//==============================================
cout << endl;
cout << endl;
cout << "###### foo_2 : template (usual) function only with second
argument ######" << endl;
cout << " All template types are explicit" << endl;
foo_2<int, int> (i12);
foo_2<int, char*> (c22);
foo_2<char*, int> (i32);
foo_2<char*, char*> (c42);
cout << endl;
cout << " First template type is explicit" << endl;
cout << " Second template type is implicit (defined according to the
arg2 type)" << endl;
foo_2<int> (i12);
foo_2<int> (c22);
foo_2<char*> (i32);
foo_2<char*> (c42);
//==============================================
cout << endl;
cout << endl;
cout << "###### foo_all : template (usual) function with all arguments
######" << endl;
cout << " All template types are explicit" << endl;
foo_all<int, int> (i11, i12);
foo_all<int, char*> (i21, c22);
foo_all<char*, int> (c31, i32);
foo_all<char*, char*> (c41, c42);
cout << endl;
cout << " First template type is explicit" << endl;
cout << " Second template type is implicit (defined according to the
arg2 type)" << endl;
foo_all<int> (i11, i12);
foo_all<int> (i21, c22);
foo_all<char*> (c31, i32);
foo_all<char*> (c41, c42);
cout << endl;
cout << " All template types are implicit (defined according to the
arguments types)" << endl;
foo_all (i11, i12);
foo_all (i21, c22);
foo_all (c31, i32);
foo_all (c41, c42);
//##############################################
//##############################################
cout << endl;
cout << endl;
cout << "###### object.Foo_no : template member function without
arguments ######" << endl;
cout << " All template types are explicit" << endl;
object.template Foo_no<int, int> ();
object.template Foo_no<int, char*> ();
object.template Foo_no<char*, int> ();
object.template Foo_no<char*, char*> ();
//============================================== cout << endl; cout <<
endl; cout << "###### object.Foo_1 : template member function only with
first argument ######" << endl; cout << " All template types are explicit"
<< endl; object.template Foo_1<int, int> (i11); object.template Foo_1<int,
char*> (i21); object.template Foo_1<char*, int> (c31); object.template
Foo_1<char*, char*> (c41);
//============================================== cout << endl; cout <<
endl; cout << "###### object.Foo_2 : template member function only with
second argument ######" << endl; cout << " All template types are explicit"
<< endl; object.template Foo_2<int, int> (i12); object.template Foo_2<int,
char*> (c22); object.template Foo_2<char*, int> (i32); object.template
Foo_2<char*, char*> (c42);
cout << endl;
cout << " First template type is explicit" << endl;
cout << " Second template type is implicit (defined according to the
arg2 type)" << endl;
object.template Foo_2<int> (i12);
object.template Foo_2<int> (c22);
object.template Foo_2<char*> (i31);
object.template Foo_2<char*> (c41);
//==============================================
cout << endl;
cout << endl;
cout << "###### object.Foo_all : template member function with all
arguments ######" << endl;
cout << " All template types are explicit" << endl;
object.template Foo_all<int, int> (i11, i12);
object.template Foo_all<int, char*> (i21, c22);
object.template Foo_all<char*, int> (c31, i32);
object.template Foo_all<char*, char*> (c41, c42);
cout << endl;
cout << " First template type is explicit" << endl;
cout << " Second template type is implicit (defined according to the
arg2 type)" << endl;
object.template Foo_all<int> (i11, i12);
object.template Foo_all<int> (i21, c22);
object.template Foo_all<char*> (c31, i32);
object.template Foo_all<char*> (c41, c42);
cout << endl;
cout << " All template types are implicit (defined according to the
arguments types)" << endl;
// ATTENTION! not object.template Foo_all (v1, v2), but object.Foo_all
(v1, v2)
object.Foo_all (i11, i12);
object.Foo_all (i21, c22);
object.Foo_all (c31, i32);
object.Foo_all (c41, c42);
//========================
return 0;
}
###################################################
############# 4. Compiler #########################
###################################################
g++ -v : gcc version egcs-2.91.57 19980901 (egcs-1.1 release)
###################################################
############# 5. Hardware #########################
###################################################
uname -a : SunOS tibamsun8 5.6 Generic_105181-09 sun4m sparc
SUNW,SPARCstation-5
###################################################
############# 6. Results of the running ##########
###################################################
###### foo_no : template (usual) function without arguments ######
All template types are explicit
void foo_no<int, int>() : No input parameters
void foo_no<int, char *>() : No input parameters
void foo_no<char *, int>() : No input parameters
void foo_no<char *, char *>() : No input parameters
###### foo_1 : template (usual) function only with first argument ######
All template types are explicit
void foo_1<int, int>(int &) : arg1 = 11
void foo_1<int, char *>(int &) : arg1 = 21
void foo_1<char *, int>(char *&) : arg1 = three_aaaaa
void foo_1<char *, char *>(char *&) : arg1 = four_aaaaa
###### foo_2 : template (usual) function only with second argument ######
All template types are explicit
void foo_2<int, int>(int &) : arg2 = 12
void foo_2<int, char *>(char *&) : arg2 = two_bbbbb
void foo_2<char *, int>(int &) : arg2 = 32
void foo_2<char *, char *>(char *&) : arg2 = four_bbbbb
First template type is explicit
Second template type is implicit (defined according to the arg2 type)
void foo_2<int, int>(int &) : arg2 = 12
void foo_2<int, char *>(char *&) : arg2 = two_bbbbb
void foo_2<char *, int>(int &) : arg2 = 32
void foo_2<char *, char *>(char *&) : arg2 = four_bbbbb
###### foo_all : template (usual) function with all arguments ###### All
template types are explicit void foo_all<int, int>(int &, int &) : arg1 =
11, arg2 = 12 void foo_all<int, char *>(int &, char *&) : arg1 = 21, arg2
= two_bbbbb void foo_all<char *, int>(char *&, int &) : arg1 = three_aaaaa,
arg2 = 32 void foo_all<char *, char *>(char *&, char *&) : arg1 =
four_aaaaa, arg2 = four_bbbbb
First template type is explicit Second template type is implicit (defined
according to the arg2 type) void foo_all<int, int>(int &, int &) : arg1 =
11, arg2 = 12 void foo_all<int, char *>(int &, char *&) : arg1 = 21, arg2
= two_bbbbb void foo_all<char *, int>(char *&, int &) : arg1 = three_aaaaa,
arg2 = 32 void foo_all<char *, char *>(char *&, char *&) : arg1 =
four_aaaaa, arg2 = four_bbbbb
All template types are implicit (defined according to the arguments types)
void foo_all<int, int>(int &, int &) : arg1 = 11, arg2 = 12 void
foo_all<int, char *>(int &, char *&) : arg1 = 21, arg2 = two_bbbbb void
foo_all<char *, int>(char *&, int &) : arg1 = three_aaaaa, arg2 = 32 void
foo_all<char *, char *>(char *&, char *&) : arg1 = four_aaaaa, arg2 =
four_bbbbb
###### object.Foo_no : template member function without arguments ######
All template types are explicit
void MyClass::Foo_no<int, int>() : No input parameters
void MyClass::Foo_no<int, char *>() : No input parameters
void MyClass::Foo_no<char *, int>() : No input parameters
void MyClass::Foo_no<char *, char *>() : No input parameters
###### object.Foo_1 : template member function only with first argument ######
All template types are explicit
void MyClass::Foo_1<int, int>(int &) : Arg1 = 11
void MyClass::Foo_1<int, char *>(int &) : Arg1 = 21
void MyClass::Foo_1<char *, int>(char *&) : Arg1 = three_aaaaa
void MyClass::Foo_1<char *, char *>(char *&) : Arg1 = four_aaaaa
###### object.Foo_2 : template member function only with second argument
###### All template types are explicit void MyClass::Foo_2<int, int>(int &)
: Arg2 = 12 void MyClass::Foo_2<int, char *>(char *&) : Arg2 = two_bbbbb
void MyClass::Foo_2<char *, int>(int &) : Arg2 = 32 void MyClass::Foo_2<char
*, char *>(char *&) : Arg2 = four_bbbbb
First template type is explicit
Second template type is implicit (defined according to the arg2 type)
void MyClass::Foo_2<int, int>(int &) : Arg2 = 12
void MyClass::Foo_2<int, char *>(char *&) : Arg2 = two_bbbbb
void MyClass::Foo_2<char *, int>(int &) : Arg2 = 31
void MyClass::Foo_2<char *, char *>(char *&) : Arg2 = four_aaaaa
###### object.Foo_all : template member function with all arguments ######
All template types are explicit
void MyClass::Foo_all<int, int>(int &, int &) : Arg1 = 11, Arg2 = 12
void MyClass::Foo_all<int, char *>(int &, char *&) : Arg1 = 21, Arg2 =
two_bbbbb
void MyClass::Foo_all<char *, int>(char *&, int &) : Arg1 = three_aaaaa,
Arg2 = 32
void MyClass::Foo_all<char *, char *>(char *&, char *&) : Arg1 =
four_aaaaa, Arg2 = four_bbbbb
First template type is explicit
Second template type is implicit (defined according to the arg2 type)
void MyClass::Foo_all<int, int>(int &, int &) : Arg1 = 11, Arg2 = 12
void MyClass::Foo_all<int, char *>(int &, char *&) : Arg1 = 21, Arg2 =
two_bbbbb
void MyClass::Foo_all<char *, int>(char *&, int &) : Arg1 = three_aaaaa,
Arg2 = 32
void MyClass::Foo_all<char *, char *>(char *&, char *&) : Arg1 =
four_aaaaa, Arg2 = four_bbbbb
All template types are implicit (defined according to the arguments types)
void MyClass::Foo_all<int, int>(int &, int &) : Arg1 = 11, Arg2 = 12
void MyClass::Foo_all<int, char *>(int &, char *&) : Arg1 = 21, Arg2 =
two_bbbbb
void MyClass::Foo_all<char *, int>(char *&, int &) : Arg1 = three_aaaaa,
Arg2 = 32
void MyClass::Foo_all<char *, char *>(char *&, char *&) : Arg1 =
four_aaaaa, Arg2 = four_bbbbb
###################################################
############# END of INFORMATION #################
###################################################
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]