function templates doesn't support default template parameters?

W

William Xu

Compiling:

template <class T = int>
T foo(const T& t)
{}

int main(int argc, char *argv[])
{}

gcc complains:

,----
| /Users/william/repo/helloworlds/foo.cpp:2: error: default template
| arguments may not be used in function templates
`----

But I find in "TC++PL(3rd, special edition)" P.340, Bjarne is giving
function templates with default template parameters as examples.

If current standard doesn't support it, what is the reason here?
 
E

Erik Wikström

Compiling:

template <class T = int>
T foo(const T& t)
{}

int main(int argc, char *argv[])
{}

gcc complains:

,----
| /Users/william/repo/helloworlds/foo.cpp:2: error: default template
| arguments may not be used in function templates
`----

But I find in "TC++PL(3rd, special edition)" P.340, Bjarne is giving
function templates with default template parameters as examples.

If current standard doesn't support it, what is the reason here?

It is not supported in the current standard (14.1 §9), I do not know why.
 
K

Kai-Uwe Bux

Erik said:
Compiling:

template <class T = int>
T foo(const T& t)
{}

int main(int argc, char *argv[])
{}

gcc complains:

,----
| /Users/william/repo/helloworlds/foo.cpp:2: error: default template
| arguments may not be used in function templates
`----

But I find in "TC++PL(3rd, special edition)" P.340, Bjarne is giving
function templates with default template parameters as examples.

If current standard doesn't support it, what is the reason here?

It is not supported in the current standard (14.1 §9), I do not know why.

I wonder what difference one should expect from

template < typename T = int >
T foo ( T const & arg );

and

template < typename T >
T foo ( T const & arg );

How would you use the default type? The type T would be deduced from the
argument anyway, wouldn't it?


Best

Kai-Uwe Bux
 
W

William Xu

Kai-Uwe Bux said:
How would you use the default type? The type T would be deduced from the
argument anyway, wouldn't it?

Consider the following example then. What if I want the default
comparision method to be Case_insensitive?

#include <iostream>

struct Case_insensitive
{
static bool eq(char c1, char c2) { return tolower(c1) == tolower(c2); }
};

struct Case_sensitive
{
static bool eq(char c1, char c2) { return c1 == c2; }
};

template <class Cmp>
bool eq(char c1, char c2)
{
return Cmp::eq(c1, c2);
}

int main(int argc, char *argv[])
{
char c1 = 'h', c2 = 'H';

/* These are okay. */
eq<Case_insensitive>(c1, c2) ;
eq<Case_sensitive>(c1, c2);

/* But how about this one ? */
/* eq(c1, c2); */

}

--
William

http://williamxu.net9.org

You know what they say -- the sweetest word in the English language is revenge.
-- Peter Beard
 
K

Kai-Uwe Bux

William said:
Kai-Uwe Bux said:
How would you use the default type? The type T would be deduced from the
argument anyway, wouldn't it?

Consider the following example then. What if I want the default
comparision method to be Case_insensitive?

#include <iostream>

struct Case_insensitive
{
static bool eq(char c1, char c2) { return tolower(c1) == tolower(c2); }
};

struct Case_sensitive
{
static bool eq(char c1, char c2) { return c1 == c2; }
};

template <class Cmp>
bool eq(char c1, char c2)
{
return Cmp::eq(c1, c2);
}

int main(int argc, char *argv[])
{
char c1 = 'h', c2 = 'H';

/* These are okay. */
eq<Case_insensitive>(c1, c2) ;
eq<Case_sensitive>(c1, c2);

/* But how about this one ? */
/* eq(c1, c2); */

}

Now, I can see your point.

On the other hand, it looks as though you want a default argument not a
default type:

#include <cctype>

bool case_insensitive ( char c1, char c2 ) {
return ( std::tolower(c1) == std::tolower(c2) );
}

bool case_sensitive ( char c1, char c2 ) {
return ( c1 == c2 );
}

typedef bool(* char_compare )(char,char);

bool eq ( char c1, char c2, char_compare comp = &case_sensitive ) {
return ( comp( c1, c2 ) );
}

int main ( void ) {
eq( 'c', 'h' );
}


Then again, I am not at all sure whether it is a good idea to have a default
in this case. I generally do not like magic hiding somewhere. Sooner or
later it is going to bite you. From that point of view, I prefer the
verbose version

eq< case_sensitive >( c1, c2 );

to

eq( c1, c2 );



Best

Kai-Uwe Bux
 
J

James Kanze

Compiling:
template <class T = int>
T foo(const T& t)
{}
int main(int argc, char *argv[])
{}
gcc complains:
But I find in "TC++PL(3rd, special edition)" P.340, Bjarne
is giving function templates with default template
parameters as examples.

That surprises me a bit (but someone walked off with my copy of
the 3rd edition, so I can't verify it).
It is not supported in the current standard (14.1 §9), I do
not know why.

Probably because originally, function template arguments could
only be deduced, not explicitly specified, and a defauld
argument doesn't make sense in that case. For that matter,
given the original poster's example, when would the default
argument be used?
 
E

Eric Pruneau

"James Kanze" <[email protected]> a écrit dans le message de
(e-mail address removed)...
Compiling:
template <class T = int>
T foo(const T& t)
{}
int main(int argc, char *argv[])
{}
gcc complains:
But I find in "TC++PL(3rd, special edition)" P.340, Bjarne
is giving function templates with default template
parameters as examples.

That surprises me a bit (but someone walked off with my copy of
the 3rd edition, so I can't verify it).
It is not supported in the current standard (14.1 §9), I do
not know why.

Probably because originally, function template arguments could
only be deduced, not explicitly specified, and a defauld
argument doesn't make sense in that case. For that matter,
given the original poster's example, when would the default
argument be used?

--

From C++ Templates (Vandevoorde, Josuttis)

"When templates were originally added to the C++ language, explicit function
template arguments were not a valid construct. [...] Since then, however, it
is possible to specify explicitle function template arguments that cannot be
deduced. "

So the following should compile...

template <typename T1, typename T2 = int>
T2 count (T1 const& x);

Cause T2 cannot be deduced since it is the return parameter. However I tried
with intel c++ 9.1 and VS 2003 compilers and they give me an error...
 
E

Erik Wikström

"James Kanze" <[email protected]> a é–rit dans le message de
(e-mail address removed)...
Compiling:
template <class T = int>
T foo(const T& t)
{}
int main(int argc, char *argv[])
{}
gcc complains:
But I find in "TC++PL(3rd, special edition)" P.340, Bjarne
is giving function templates with default template
parameters as examples.

That surprises me a bit (but someone walked off with my copy of
the 3rd edition, so I can't verify it).
It is not supported in the current standard (14.1 � I do
not know why.

Probably because originally, function template arguments could
only be deduced, not explicitly specified, and a defauld
argument doesn't make sense in that case. For that matter,
given the original poster's example, when would the default
argument be used?

--

From C++ Templates (Vandevoorde, Josuttis)

"When templates were originally added to the C++ language, explicit function
template arguments were not a valid construct. [...] Since then, however, it
is possible to specify explicitle function template arguments that cannot be
deduced. "

So the following should compile...

template <typename T1, typename T2 = int>
T2 count (T1 const& x);

Cause T2 cannot be deduced since it is the return parameter. However I tried
with intel c++ 9.1 and VS 2003 compilers and they give me an error...

From the standard, 14.1 §9:

A default template-argument is a template-argument (14.3) specified
after = in a template-parameter. A default template-argument may be
specified for any kind of template-parameter (type, non-type, template).
A default template-argument may be specified in a class template
declaration or a class template definition. A default template-argument
shall not be specified in a function template declaration or a function
template definition, nor in the template-parameter-list of the
definition of a member of a class template. A default template-argument
shall not be specified in a friend template declaration.
 
T

Triple-DES

From C++ Templates (Vandevoorde, Josuttis)

"When templates were originally added to the C++ language, explicit function
template arguments were not a valid construct. [...] Since then, however, it
is possible to specify explicitle function template arguments that cannot be
deduced. "

You actually snipped an important sentence here:
"As a result, there seemed to be no compelling reason to allow default
function template arguments because the default would always be
overriden by the deduced value."
So the following should compile...

template <typename T1, typename T2 = int>
T2 count (T1 const& x);

Cause T2 cannot be deduced since it is the return parameter. However I tried
with intel c++ 9.1 and VS 2003 compilers and they give me an error...

The sentence I quoted above should make it clear that the examples in
the book illustrate how default template arguments would be used if
they were allowed, and are not well-formed c++.

DP
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top