Topic: Default values for template function parameters used to deduce template arguments
Author: sbnaran@localhost.localdomain.COM (Siemel Naran)
Date: 1998/12/05 Raw View
On 4 Dec 1998 16:59:25 GMT, Vlad Harchev <vladhar@imimail.ssau.ru> wrote:
>Is the following code correct?
>
>template <class T1,class T2>
>void f(T1 v1,T2 v2=3) { };
This is not correct in general because there may not be a conversion
from 'int' (the number '3') to T2. For example:
f<std::plus<int> >(5);
Supposing we aren't this explicit. Say we write
f(5);
The compiler can deduce that T1 is 'int'. If the compiler is allowed
to deduce the type of T2 from the default argument -- that is, T2 is
an 'int' -- then the call works and we call f<int,int>(5,3). If the
compiler is not allowed to deduce types from default arguments, then
the call is undefined. The latter point of view is the correct one:
14.8.2.4 Deducing template arguments from a type [temp.deduct.type]
(17)
A template type-parameter cannot be deduced from the type of a function
default argument. [Example:
template <class T> void f(T=5, T=7);
void g()
{
f(1); // OK: call f<int>(1,7)
f(); // error: cannot deduce T
f<int>(); // OK: call f<int>(5,7)
}
I don't see any deep reason why rule 17 exists. I guess the ability
to deduce types from default arguments would conflict would default
template arguments (see below for a comment on default arguments in
function templates).
>I mean - whether default arguments for template function parameters are
>allowed? I haven't found anything definite in CD2. I think allowing this
>can be very useful, consider the following:
>
>template <class T1,class T2> struct is_equ_types { enum { ans=0 }; };
>template <class T> struct is_equ_types<T,T> { enum { ans=1 }; };
>
>struct nothing {} //unique class
>
>//this dumps all passed arguments that were actually passed. More parameters
>//can be added thus usability increased
>
>template <class O,class T1,class T2,class T3,class T4>
>void dump(O& o,const T1& v1=nothing(),const T2& v2=nothing(),
> const T3& v3=nothing(),const T4& v4=nothing())
A few months ago on this newsgroup, Stroustrup pointed out that default
arguments for function templates should have been allowed; and in
their examples to one another, the committee used functions with default
template arguments. Thanks to template argument deduction, default
arguments for function templates are not generally needed. So I guess
they forgot about it. See this message on www.dejanews.com:
98/10/17
Q: templates and default
comp.lang.c++.moderated
Bjarne Stroustrup
>Note: the following code compiles with Borland C++ 5.2, but fails on
>GCC 2.7.2, EGCS 1.1b.
Como also doesn't like it.
"tmp.c", line 10: error: no instance of function template "f" matches the
argument list
argument types are: (int)
f(4);
^
>#include <iostream>
>template <class T,class T1>
>void f(T v,T1 v1=4)
>{
> cout << v << " " << v1;
>};
>void main()
>{
> f(3,3);
> f(4);
>}
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ 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: "Vlad Harchev" <vladhar@imimail.ssau.ru>
Date: 1998/12/04 Raw View
Is the following code correct?
template <class T1,class T2>
void f(T1 v1,T2 v2=3) { };
I mean - whether default arguments for template function parameters are
allowed? I haven't found anything definite in CD2. I think allowing this
can be very useful, consider the following:
template <class T1,class T2> struct is_equ_types { enum { ans=0 }; };
template <class T> struct is_equ_types<T,T> { enum { ans=1 }; };
struct nothing {} //unique class
//this dumps all passed arguments that were actually passed. More parameters
//can be added thus usability increased
template <class O,class T1,class T2,class T3,class T4>
void dump(O& o,const T1& v1=nothing(),const T2& v2=nothing(),
const T3& v3=nothing(),const T4& v4=nothing())
{
if ( !is_equ_types<T1,nothing>::ans )
{
o << v1;
if ( !is_equ_types<T2,nothing>::ans )
{
o << " " << v2;
if ( !is_equ_types<T3,nothing>::ans )
{
o << " " << v3;
if ( !is_equ_types<T4,nothing>::ans )
{
o << " " << v4;
}
}
}
};
}
//usage
void f()
{
dump(cout,"foo",3,4,5); dump(cout,4.4);
}
GCC 2.7.2, and EGCS 1.1b don't accept it.
Note: the following code compiles with Borland C++ 5.2, but fails on
GCC 2.7.2, EGCS 1.1b.
#include <iostream>
template <class T,class T1>
void f(T v,T1 v1=4)
{
cout << v << " " << v1;
};
void main()
{
f(3,3);
f(4);
}
So, if this is not allowed or nothing is said in final standard, IMO it will
be nice to allow this.
- Vlad
[ 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 ]