Topic: Default template arguments in function templates


Author: "George Sakkis" <gsakkis@rutgers.edu>
Date: 5 Oct 2005 04:40:02 GMT
Raw View
Hi all,

I have the following two template function definitions:

template <typename Container, typename Sepatator>
string join(const Container& c, const Sepatator& s) {
    // ...
}

template <typename Container>
string join(const Container& c) {
    return join(c, ' ');
}

I tried to merge them into one using a default argument for Separator,
but the compiler (gcc 3.3.1) complains that default template arguments
may not be used in function templates. What's the reason for this
limitation and, more importantly, is there a workaround or I have to
leave it to this ?

TIA,
George

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Jaakko =?iso-8859-1?Q?J=E4rvi?= <jaakko.jarvi@cs.utu.fi>
Date: 1999/03/16
Raw View
Hello,

Default template arguments are not currently allowed in function
templates.
Stroustrup however (C++ 3ed, p.340) uses them and in his homepages says:

"Due to an unfortunate oversight, the standard simply bans default
arguments for template paramenters for a function template. I have
submitted a
defect report on this."

What might be the situation now?

Furthermore, if default template arguments will be ok in the future,
would it have any consequencies to the template argument deduction?

For example:

class A {};
A a;
class B {};
B b;

template <class T =3D A> f(T x =3D a);=20

....

f(b); // T can be deduced, should this be a call to f<B>(b) ???
f();  // Now T can't be deduced, i.e. default would be used leading to
f<A>(a) ???



Regards=20

Jaakko J=E4rvi
Turku Centre for Computer Science, Finland
jaakko.jarvi@cs.utu.fi
---
[ 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: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/03/16
Raw View
On 16 Mar 99 11:38:25 GMT, Jaakko J=E4rvi <jaakko.jarvi@cs.utu.fi> wrote:

>What might be the situation now?

No bug defect as yet.


>Furthermore, if default template arguments will be ok in the future,
>would it have any consequencies to the template argument deduction?
>
>For example:
>
>class A {};
>A a;
>class B {};
>B b;
>
>template <class T =3D A> f(T x =3D a);=20

Actually, the standard prohibits default function arguments from
participating in template argument deduction.  Eg,
   template <class T> void f(T x=3D1);
   int main() { f(); } // can't call f<int>(1)
So even if default template arguments for functions are allowed,
there is no problem.


>f(b); // T can be deduced, should this be a call to f<B>(b) ???

Fine.

>f();  // Now T can't be deduced, i.e. default would be used leading to
>f<A>(a) ???

No, the standard prohibits this.

--=20
----------------------------------
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: Alex Vinokur <alexander.vinokur@telrad.co.il>
Date: 1999/03/18
Raw View
In article <36EE3145.DE7E6831@cs.utu.fi>,
  Jaakko =?iso-8859-1?Q?J=E4rvi?= <jaakko.jarvi@cs.utu.fi> wrote:
> Hello,
>
> Default template arguments are not currently allowed in function
> templates.
[snip]

Hi,

Here is an example. We see that
        1. when calling
           template function gets its missing template-type
           according to its argument type.
        2. when creating object (of template class)
           template class gets its missing template-type
           according to the class template default.

Conclusions.  1. There is no difference between calling functions  according
to the following declarations :  template <typename T = A> void foo1
(-something-) {}  template <typename T>  void foo2 (-something-) {}  (See
functions : f1 () and f2 (); f3 () and f5 (); f4 () and f6 ()).

        2. There is the difference between creating objects
              according to the following declarations :
           template <typename T = A> class COO1 () {}
           template <typename T>     class COO2 () {}
           (See classes : C1 and C2; C3 and C5; C4 and C6).


        Thanks,
        Alex


//######################################################
//################# 1. main.C ##########################
//######################################################

#include <string>

class A {};
A a;
class B {};
B b;

//======================================
template <typename T = A>
void f1 () { cout << __PRETTY_FUNCTION__ << endl; }
// __PRETTY_FUNCTION__ is predefined variable in GNU gcc/g++

template <typename T>
void f2 () { cout << __PRETTY_FUNCTION__ << endl; }


template <typename T = A>
void f3 (T x = a) { cout << __PRETTY_FUNCTION__ << endl; }

template <typename T = A>
void f4 (T x) { cout << __PRETTY_FUNCTION__ << endl; }


template <typename T>
void f5 (T x = a) { cout << __PRETTY_FUNCTION__ << endl; }

template <typename T>
void f6 (T x) { cout << __PRETTY_FUNCTION__ << endl; }
//======================================

//======================================
template <typename T = A>
class C1 { public : C1 () { cout << __PRETTY_FUNCTION__ << endl;} };

template <typename T>
class C2 { public : C2 () {cout << __PRETTY_FUNCTION__ << endl;} };

template <typename T = A>
class C3 { public : C3 (T x = a) {cout << __PRETTY_FUNCTION__ << endl;} };

template <typename T = A>
class C4 { public : C4 (T x) {cout << __PRETTY_FUNCTION__ << endl;} };

template <typename T>
class C5 { public : C5 (T x = a) {cout << __PRETTY_FUNCTION__ << endl;} };

template <typename T>
class C6 { public : C6 (T x) {cout << __PRETTY_FUNCTION__ << endl;} };


//======================================


int main ()
{
        //===============
        // f1 ();       ## no matching function for call to `f1 ()'
        // f1<> ();     ## no matching function for call to `f1 ()'
        f1<A> ();
        f1<B> ();
        //===============
        // f2 ();       ## no matching function for call to `f2 ()'
        // f2<> ();     ## no matching function for call to `f2 ()'
        f2<A> ();
        f2<B> ();
        //===============
        // f3 ();       ## no matching function for call to `f3 ()'
        // f3<> ();     ## no matching function for call to `f3 ()'
        f3<A> ();

        f3 (a);         // f3 (a) is f3<A> (a) according to the a type
        f3<> (a);       // f3 (a) is f3<A> (a) according to the a type
        f3<A> (a);

        f3 (b);         // f3 (b) is f3<B> (b) according to the b type
        f3<> (b);       // f3 (b) is f3<B> (b) according to the b type
        f3<B> (b);
        //===============
        // f4 ();       ## no matching function for call to `f4 ()'
        // f4<> ();     ## no matching function for call to `f4 ()'
        // f4<A> ();    ## no matching function for call to `f4 ()'

        f4 (a);         // f4 (a) is f4<A> (a) according to the a type
        f4<> (a);       // f4 (a) is f4<A> (a) according to the a type
        f4<A> (a);

        f4 (b);         // f4 (b) is f4<B> (b) according to the b type
        f4<> (b);       // f4 (b) is f4<B> (b) according to the b type
        f4<B> (b);
        //===============
        // f5 ();       ## no matching function for call to `f5 ()'
        // f5<> ();     ## no matching function for call to `f5 ()'
        f5<A> ();

        f5 (a);         // f5 (a) is f5<A> (a) according to the a type
        f5<> (a);       // f5 (a) is f5<A> (a) according to the a type
        f5<A> (a);

        f5 (b);         // f5 (b) is f5<B> (b) according to the b type
        f5<> (b);       // f5 (b) is f5<B> (b) according to the b type
        f5<B> (b);
        //===============
        // f6 ();       ## no matching function for call to `f6 ()'
        // f6<> ();     ## no matching function for call to `f6 ()'
        // f6<A> ();    ## no matching function for call to `f6 ()'

        f6 (a);         // f6 (a) is f6<A> (a) according to the a type
        f6<> (a);       // f6 (a) is f6<A> (a) according to the a type
        f6<A> (a);

        f6 (b);         // f6 (b) is f6<B> (b) according to the b type
        f6<> (b);       // f6 (b) is f6<B> (b) according to the b type
        f6<B> (b);
        //===============
// C1   c10;            ## `C1' undeclared (first use this function)
C1<>    c11;            // c11 is C1<A>() according to the template default
C1<A>   c12;
C1<B>   c13;
        //===============
C2<A>   c21;
C2<B>   c22;
        //===============
C3<>    c31;            // c31 is C1<A>() according to the template default
C3<A>   c32;

C3<>    c33 (a);        // c33 is C1<A>() according to the template default
// C3<> c34 (b);        ## no matching function for call to `C3<A>::C3 (B &)
C3<A>   c35 (a);

C3<B>   c36 (b);
        //===============
C4<>    c41 (a);        // c41 is C1<A>() according to the template default
C4<A>   c42 (a);

C4<B>   c43 (b);
        //===============
C5<A>   c51;

C5<A>   c52 (a);

C5<B>   c53 (b);
        //===============
C6<A>   c61 (a);

C6<B>   c62 (b);
        //===============
        return 0;
}


//######################################################
//########### 2. The results of the running ############
//######################################################

void f1<A>()
void f1<B>()
void f2<A>()
void f2<B>()
void f3<A>(class A = a)
void f3<A>(class A = a)
void f3<A>(class A = a)
void f3<A>(class A = a)
void f3<B>(class B = a)
void f3<B>(class B = a)
void f3<B>(class B = a)
void f4<A>(class A)
void f4<A>(class A)
void f4<A>(class A)
void f4<B>(class B)
void f4<B>(class B)
void f4<B>(class B)
void f5<A>(class A = a)
void f5<A>(class A = a)
void f5<A>(class A = a)
void f5<A>(class A = a)
void f5<B>(class B = a)
void f5<B>(class B = a)
void f5<B>(class B = a)
void f6<A>(class A)
void f6<A>(class A)
void f6<A>(class A)
void f6<B>(class B)
void f6<B>(class B)
void f6<B>(class B)
C1<A>::C1<A>()
C1<A>::C1<A>()
C1<B>::C1<B>()
C2<A>::C2<A>()
C2<B>::C2<B>()
C3<A>::C3<A>(class A = a)
C3<A>::C3<A>(class A = a)
C3<A>::C3<A>(class A = a)
C3<A>::C3<A>(class A = a)
C3<B>::C3<B>(class B = a)
C4<A>::C4<A>(class A)
C4<A>::C4<A>(class A)
C4<B>::C4<B>(class B)
C5<A>::C5<A>(class A = a)
C5<A>::C5<A>(class A = a)
C5<B>::C5<B>(class B = a)
C6<A>::C6<A>(class A)
C6<B>::C6<B>(class B)

//######################################################
//########### 3. Compiler ##############################
//######################################################
g++ -v : gcc version egcs-2.91.57 19980901 (egcs-1.1 release)


//######################################################
//########### 4. System ################################
//######################################################
uname -a : SunOS <nodename> 5.6 Generic_105181-09
           sun4m sparc SUNW,SPARCstation-5

//######################################################
//########### 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              ]