Function templates

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • al

    Function templates

    1. If a function template is defined:

    template <typename A>
    A SQ(A& a)
    {
    return a*a;
    }

    How could prevent users from passing a type which makes no sense, like
    Employee class type?

    2. If Employee is pass as T in the template below, should an assignment
    operator have to be defined since there're assignment operation in the
    function?

    template <class T>
    void swap(T& x, T& y)
    {
    T temp;
    temp = x;
    x = y;
    y = temp;
    }

    3. Is "template <class T>" equivalent to "template <typename T>"?

    Thanks!



  • Ron Natalie

    #2
    Re: Function templates


    "al" <allin@168.ne t> wrote in message news:ne1Kb.5976 91$0v4.23531031 @bgtnsc04-news.ops.worldn et.att.net...[color=blue]
    > 1. If a function template is defined:
    >
    > How could prevent users from passing a type which makes no sense, like
    > Employee class type?[/color]

    You can't, anymore than you can stop them from writing
    Employee() * Employee()
    other than the compiler bitching about * not being defined for those
    types.
    [color=blue]
    >
    > 2. If Employee is pass as T in the template below, should an assignment
    > operator have to be defined since there're assignment operation in the
    > function?[/color]

    There has to be one accessible. Of course, operator= will be defined
    in a class if the user doesn't declare one.
    [color=blue]
    > 3. Is "template <class T>" equivalent to "template <typename T>"?[/color]

    Yes. <class T> will match any type, not just class types. Typename
    and class are interchangeable in this context.

    Comment

    • Cy Edmunds

      #3
      Re: Function templates

      "al" <allin@168.ne t> wrote in message
      news:ne1Kb.5976 91$0v4.23531031 @bgtnsc04-news.ops.worldn et.att.net...[color=blue]
      > 1. If a function template is defined:
      >
      > template <typename A>
      > A SQ(A& a)
      > {
      > return a*a;
      > }
      >
      > How could prevent users from passing a type which makes no sense, like
      > Employee class type?[/color]

      Let 'em try. It won't compile. Of course the error message may be a bit
      obscure.
      [color=blue]
      >
      > 2. If Employee is pass as T in the template below, should an assignment
      > operator have to be defined since there're assignment operation in the
      > function?
      >
      > template <class T>
      > void swap(T& x, T& y)
      > {
      > T temp;
      > temp = x;
      > x = y;
      > y = temp;
      > }[/color]

      If you don't write an assignment operator the compiler will provide you with
      one which just copies the bits.
      [color=blue]
      >
      > 3. Is "template <class T>" equivalent to "template <typename T>"?[/color]

      Yes. The keyword "typename" was a relatively late addition to the language.
      It makes more sense in this context then "class".
      [color=blue]
      >
      > Thanks!
      >
      >
      >[/color]

      --
      Cy



      Comment

      • Gianni Mariani

        #4
        Re: Function templates

        al wrote:[color=blue]
        > 1. If a function template is defined:
        >
        > template <typename A>
        > A SQ(A& a)
        > {
        > return a*a;
        > }
        >
        > How could prevent users from passing a type which makes no sense, like
        > Employee class type?[/color]

        You can create a specialization like:

        template <typename A>
        A SQ(A& a)
        {
        return a*a;
        }

        template <>
        Employee SQ(Employee& a)
        {
        ... some code that compiles to an error ...
        }

        However if you don't provide a 'operator *()', your original SQ provides
        for an error anyway.


        Comment

        • Ron Natalie

          #5
          Re: Function templates


          "Cy Edmunds" <cedmunds@spaml ess.rochester.r r.com> wrote in message news:Wx1Kb.5275 8$q55.15281@twi ster.nyroc.rr.c om...
          [color=blue]
          > If you don't write an assignment operator the compiler will provide you with
          > one which just copies the bits.[/color]

          Well, more specifically, it invokes the assignment semantics of all the subobjects
          (bases and non-static members).[color=blue][color=green]
          > >[/color][/color]

          Comment

          • Cy Edmunds

            #6
            Re: Function templates

            "Ron Natalie" <ron@sensor.com > wrote in message
            news:3ff873ac$0 $31832$9a6e19ea @news.newshosti ng.com...[color=blue]
            >
            > "Cy Edmunds" <cedmunds@spaml ess.rochester.r r.com> wrote in message[/color]
            news:Wx1Kb.5275 8$q55.15281@twi ster.nyroc.rr.c om...[color=blue]
            >[color=green]
            > > If you don't write an assignment operator the compiler will provide you[/color][/color]
            with[color=blue][color=green]
            > > one which just copies the bits.[/color]
            >
            > Well, more specifically, it invokes the assignment semantics of all the[/color]
            subobjects[color=blue]
            > (bases and non-static members).[color=green][color=darkred]
            > > >[/color][/color]
            >[/color]

            Right! When I first started C++ I worried about that.

            --
            Cy



            Comment

            • Rolf Magnus

              #7
              Re: Function templates

              Chris Mantoulidis wrote:
              [color=blue]
              > "Cy Edmunds" <cedmunds@spaml ess.rochester.r r.com> wrote in message
              > news:<Wx1Kb.527 58$q55.15281@tw ister.nyroc.rr. com>...[color=green]
              >> "al" <allin@168.ne t> wrote in message
              >> news:ne1Kb.5976 91$0v4.23531031 @bgtnsc04-news.ops.worldn et.att.net...[color=darkred]
              >> > 1. If a function template is defined:
              >> >
              >> > template <typename A>
              >> > A SQ(A& a)
              >> > {
              >> > return a*a;
              >> > }
              >> >
              >> > How could prevent users from passing a type which makes no sense,
              >> > like Employee class type?[/color]
              >>
              >> Let 'em try. It won't compile. Of course the error message may be a
              >> bit obscure.
              >>[color=darkred]
              >> >
              >> > 2. If Employee is pass as T in the template below, should an
              >> > assignment operator have to be defined since there're assignment
              >> > operation in the function?
              >> >
              >> > template <class T>
              >> > void swap(T& x, T& y)
              >> > {
              >> > T temp;
              >> > temp = x;
              >> > x = y;
              >> > y = temp;
              >> > }[/color]
              >>
              >> If you don't write an assignment operator the compiler will provide
              >> you with one which just copies the bits.
              >>[color=darkred]
              >> >
              >> > 3. Is "template <class T>" equivalent to "template <typename T>"?[/color]
              >>
              >> Yes. The keyword "typename" was a relatively late addition to the
              >> language. It makes more sense in this context then "class".[/color]
              >
              >
              > So, <class T> allows ANY KINDA class and type (int, char, etc.) to be
              > passed as the template whereas <template T> allows just types??[/color]

              What do you mean by "just types"? classes _are_ types.
              [color=blue]
              > Is that it? Cuz I'm a bit confused.[/color]

              Again, there is no difference between <class T> and <typename T> (not
              <template T> btw - I guess that was a typo).

              Comment

              • Chris Mantoulidis

                #8
                Re: Function templates

                Jacques Labuschagne <jacques@clawsh rimp.com> wrote in message news:<vo8Kb.158 31$ws.1748349@n ews02.tsnz.net> ...[color=blue]
                > Chris Mantoulidis wrote:[color=green]
                > > So, <class T> allows ANY KINDA class and type (int, char, etc.) to be
                > > passed as the template whereas <template T> allows just types?? Is
                > > that it? Cuz I'm a bit confused.[/color]
                >
                > No, the two are equivalent. You can't restrict T, but you can use T in
                > such a way that it only compiles with compatible types.[/color]

                compatible types = int, char, etc. ???


                Then what's the difference between typename and class... You don't really explain

                Thanks,
                cmad
                [color=blue]
                >
                > template<typena me T>
                > void foo(const T& some_object){
                > some_object.unu sual_function() ;
                > }
                >
                > or even
                >
                > template<typena me T>
                > T bar(const T& some_object){
                > T other_object; // requires T default constructable.
                > other_object = some_object; // requires T copyable.
                > return some_object + other_object; // requires operator+
                > }[/color]

                Comment

                • Jacques Labuschagne

                  #9
                  Re: Function templates

                  Chris Mantoulidis wrote:[color=blue]
                  > Jacques Labuschagne <jacques@clawsh rimp.com> wrote in message news:<vo8Kb.158 31$ws.1748349@n ews02.tsnz.net> ...
                  >[color=green]
                  >>Chris Mantoulidis wrote:
                  >>[color=darkred]
                  >>>So, <class T> allows ANY KINDA class and type (int, char, etc.) to be
                  >>>passed as the template whereas <template T> allows just types?? Is
                  >>>that it? Cuz I'm a bit confused.[/color]
                  >>
                  >>No, the two are equivalent. You can't restrict T, but you can use T in
                  >>such a way that it only compiles with compatible types.[/color]
                  >
                  >
                  > compatible types = int, char, etc. ???[/color]

                  Compatible types == ones supporting the required operations (assignment,
                  default construction, etc). There's no difference between fundamental
                  types (int, char, etc) and user-defined types from a template's point of
                  view.
                  [color=blue]
                  >
                  >
                  > Then what's the difference between typename and class... You don't really explain
                  >[/color]

                  I said the two are equivalent. There is no difference.

                  Jacques.

                  Comment

                  • Howard Hinnant

                    #10
                    Re: Function templates

                    In article <vo8Kb.15831$ws .1748349@news02 .tsnz.net>,
                    Jacques Labuschagne <jacques@clawsh rimp.com> wrote:
                    [color=blue]
                    > You can't restrict T, but you can use T in
                    > such a way that it only compiles with compatible types.[/color]

                    You can also restrict T for the purpose of guiding overload resolution
                    (though it is far from clear that that is what the OP needed). Search
                    for "restrict_t o" and "enable_if" .

                    -Howard

                    Comment

                    • Rob Williscroft

                      #11
                      Re: Function templates

                      Howard Hinnant wrote in news:hinnant-36EA5C.08564805 012004@syrcnyrd rs-01-
                      ge0.nyroc.rr.co m:
                      [color=blue]
                      > In article <vo8Kb.15831$ws .1748349@news02 .tsnz.net>,
                      > Jacques Labuschagne <jacques@clawsh rimp.com> wrote:
                      >[color=green]
                      >> You can't restrict T, but you can use T in
                      >> such a way that it only compiles with compatible types.[/color]
                      >
                      > You can also restrict T for the purpose of guiding overload resolution
                      > (though it is far from clear that that is what the OP needed). Search
                      > for "restrict_t o" and "enable_if" .
                      >[/color]

                      It actually doesn't do a bad job at all:

                      g++ -O2 -W -Wall -pedantic -ansi -o test-gcc.exe test.cpp
                      compiling:
                      test.cpp: In function `int main()':
                      test.cpp:76: no matching function for call to `SQ(A)'

                      cl /W3 /Za /Zc:forScope,wch ar_t /GR /O2 /TP /EHs test.cpp
                      compiling:
                      test.cpp
                      test.cpp:76: error C2893: Failed to specialize function template
                      'restrict_to<T,
                      can_multiply<T> ::value>::type SQ(const T &)'
                      With the following template arguments:
                      'A'

                      bccx -O2 -w-8027 -otest-cbx.exe test.cpp
                      compiling:
                      Borland C++ 6.0 Preview for Win32 Copyright (c) 1993, 2003 Borland
                      Error test.cpp 76: no instance of function template "SQ" matches the
                      argument list

                      A lot of typing for a clean error message though:

                      #include <iostream>
                      #include <ostream>
                      #include <iomanip>

                      namespace detail
                      {
                      struct unique {};

                      typedef char False;
                      typedef char (&True)[2];

                      template < typename T >
                      unique operator * ( T const &, T const & );

                      template < typename X >
                      False is_unique( X const & );
                      True is_unique( unique );

                      template < typename T > T const &c_ref();

                      /* Simplistic implementation, doesn't check wether
                      T * T is convertable to T
                      */
                      template < typename T > struct can_multiply
                      {
                      static bool const value =
                      sizeof( is_unique( c_ref< T >() * c_ref< T >() ) )
                      ==
                      sizeof( False )
                      ;
                      };
                      } /* detail:: */


                      template < typename T >
                      struct can_multiply : detail::can_mul tiply< T >
                      {
                      };


                      template < typename T, bool False > struct restrict_to
                      {
                      };
                      template < typename T> struct restrict_to< T, true >
                      {
                      typedef T type;
                      };


                      template < typename T >
                      typename restrict_to< T, can_multiply< T >::value >::type
                      SQ( T const &a )
                      {
                      return a * a;
                      }

                      struct A {};

                      #define FAIL

                      int main()
                      {
                      using namespace std;

                      cerr << boolalpha;

                      cerr << can_multiply< int >::value << '\n';
                      cerr << can_multiply< A >::value << '\n';

                      cerr << SQ( 3 ) << '\n';

                      #if defined( FAIL )

                      cerr << SQ ( A() ) << '\n'; // line 76

                      #endif
                      }

                      Rob.
                      --

                      Comment

                      • Chris Mantoulidis

                        #12
                        Re: Function templates

                        Jacques Labuschagne <jacques@clawsh rimp.com> wrote in message news:<q4bKb.158 68$ws.1756220@n ews02.tsnz.net> ...[color=blue]
                        > Chris Mantoulidis wrote:[color=green]
                        > > Jacques Labuschagne <jacques@clawsh rimp.com> wrote in message news:<vo8Kb.158 31$ws.1748349@n ews02.tsnz.net> ...
                        > >[color=darkred]
                        > >>Chris Mantoulidis wrote:
                        > >>
                        > >>>So, <class T> allows ANY KINDA class and type (int, char, etc.) to be
                        > >>>passed as the template whereas <template T> allows just types?? Is
                        > >>>that it? Cuz I'm a bit confused.
                        > >>
                        > >>No, the two are equivalent. You can't restrict T, but you can use T in
                        > >>such a way that it only compiles with compatible types.[/color]
                        > >
                        > >
                        > > compatible types = int, char, etc. ???[/color]
                        >
                        > Compatible types == ones supporting the required operations (assignment,
                        > default construction, etc). There's no difference between fundamental
                        > types (int, char, etc) and user-defined types from a template's point of
                        > view.
                        >[color=green]
                        > >
                        > >
                        > > Then what's the difference between typename and class... You don't really explain
                        > >[/color]
                        >
                        > I said the two are equivalent. There is no difference.
                        >
                        > Jacques.[/color]

                        Then no need to have 2 (class & typename) is there?

                        Comment

                        • Howard Hinnant

                          #13
                          Re: Function templates

                          In article <Xns94679E4D3C8 D6ukcoREMOVEfre enetrtw@195.129 .110.204>,
                          Rob Williscroft <rtw@freenet.RE MOVE.co.uk> wrote:
                          [color=blue]
                          > It actually doesn't do a bad job at all:[/color]
                          ....[color=blue]
                          > A lot of typing for a clean error message though:[/color]

                          <chuckle> Yup!

                          For better error messages I see no better solution that static_assert:



                          restrict_to is good for cases when what you want is not an error
                          message, but rather the selection of another overload (possibly one
                          you're not even aware of when you write your restricted template
                          function). Maybe something like:

                          template < typename T >
                          typename restrict_to
                          <
                          T,
                          can_multiply< T >::value[color=blue]
                          >::type[/color]
                          square( T const &a )
                          {
                          return a * a;
                          }

                          template < typename T >
                          typename restrict_to
                          <
                          void,
                          can_dance< T >::value[color=blue]
                          >::type[/color]
                          square( T &a )
                          {
                          ...
                          }

                          -Howard

                          Comment

                          • Jacques Labuschagne

                            #14
                            Re: Function templates

                            Chris Mantoulidis wrote:[color=blue]
                            > Then no need to have 2 (class & typename) is there?[/color]

                            No need. Most people seem to use typename, but others prefer class.

                            Comment

                            Working...