Template Specialisation

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • johnbrown105@hotmail.com

    #1

    Template Specialisation

    Is it possible to force the compiler to use a generic template rather
    than a
    matching specialisation?

    Consider the following:

    ////////////////////////////////////////// template.cpp starts here

    #include <iostream>
    #include <ostream>


    template<class T>
    void f(T t)
    {
    std::cout << "template<T void f(T t) called: t == " << t
    << std::endl;
    }


    template<void f<int>(int i)
    {
    std::cout << "specialisa tion void f<int>(int i) called: i == "
    << i << std::endl;
    }

    void f(int j){
    std::cout << "overloaded void f(int j) called: j == "
    << j << std::endl;
    }

    int main()
    {
    f(1); // simple function matches before template
    f<int>(2); // specialisation
    f<>(3); // no need to spell out <int>, because it *must* be int
    f('4'); // template matches - f<char>(char)
    return 0;
    }

    ////////////////////////////////////////// template.cpp ends here

    Is there a way to call f with an int parameter so that the generic
    f<T>
    is called instead of the f<intspecialisa tion?

    I don't want to do this, and I cannot think of a reason for doing it.
    I'm just wondering.
  • Matthias Buelow

    #2
    Re: Template Specialisation

    johnbrown105@ho tmail.com wrote:
    Is there a way to call f with an int parameter so that the generic
    f<Tis called instead of the f<intspecialisa tion?
    There is no f<T>, a template is kind of a compiler macro, the compiler
    generates functions only if you instantiate a template (expand the
    macro, in other words).

    Comment

    • johnbrown105@hotmail.com

      #3
      Re: Template Specialisation

      On Nov 23, 9:49 am, Matthias Buelow <m...@incubus.d ewrote:
      johnbrown...@ho tmail.com wrote:
      Is there a way to call f with an int parameter so that the generic
      f<Tis called instead of the f<intspecialisa tion?
      >
      There is no f<T>, a template is kind of a compiler macro, the compiler
      generates functions only if you instantiate a template (expand the
      macro, in other words).
      I understand that. Consider the output of the program that I posted:

      overloaded void f(int j) called: j == 1
      specialization void f<int>(int i) called: i == 2
      specialization void f<int>(int i) called: i == 3
      template<Tvoid f(T t) called: t == 4

      Is there a way to write a call to f(5), so that the output would be:
      template<Tvoid f(T t) called: t == 5
      Never mind the semantic accuracy or elegance (or lack thereof!) of
      what I wrote. If this is what we are aiming for, I suppose the
      question
      would be:

      Is there a way to make the compiler generate its own instantiation,
      rather than use the explicit one that I provided? When asked this way,
      it would seem that the answer would be no, because if it generated its
      own instantiation, it would be a duplicate symbol, because mine
      already
      exists.

      Still, one never knows if the Powers That Be thought of some clever
      reason to allow this, that mere mortals such as myself could not.
      That's why I'm asking.

      Comment

      • Tadeusz B. Kopec

        #4
        Re: Template Specialisation

        On Fri, 23 Nov 2007 06:39:05 -0800, johnbrown105 wrote:
        Is it possible to force the compiler to use a generic template rather
        than a
        matching specialisation?
        >
        Consider the following:
        >
        ////////////////////////////////////////// template.cpp starts here
        >
        #include <iostream>
        #include <ostream>
        >
        >
        template<class T>
        void f(T t)
        {
        std::cout << "template<T void f(T t) called: t == " << t
        << std::endl;
        }
        >
        >
        template<void f<int>(int i)
        {
        std::cout << "specialisa tion void f<int>(int i) called: i == "
        << i << std::endl;
        }
        >
        void f(int j){
        std::cout << "overloaded void f(int j) called: j == "
        << j << std::endl;
        }
        >
        int main()
        {
        f(1); // simple function matches before template f<int>(2);
        // specialisation
        f<>(3); // no need to spell out <int>, because it *must* be int
        f('4'); // template matches - f<char>(char) return 0;
        }
        >
        ////////////////////////////////////////// template.cpp ends here
        >
        Is there a way to call f with an int parameter so that the generic f<T>
        is called instead of the f<intspecialisa tion?
        f(3u) or f<unsigned>(3) would be OK?

        --
        Tadeusz B. Kopec (tkopec@NOSPAMP LEASElife.pl)
        Great minds run in great circles.

        Comment

        • John Scheldroup

          #5
          Re: Template Specialisation


          <johnbrown105@h otmail.comwrote in message news:552510ac-545a-4b28-880f-07a06b322b62@i1 2g2000prf.googl egroups.com...
          On Nov 23, 9:49 am, Matthias Buelow <m...@incubus.d ewrote:
          >johnbrown...@h otmail.com wrote:
          Is there a way to call f with an int parameter so that the generic
          f<Tis called instead of the f<intspecialisa tion?
          >>
          >There is no f<T>, a template is kind of a compiler macro, the compiler
          >generates functions only if you instantiate a template (expand the
          >macro, in other words).
          >
          I understand that. Consider the output of the program that I posted:
          >
          overloaded void f(int j) called: j == 1
          specialization void f<int>(int i) called: i == 2
          specialization void f<int>(int i) called: i == 3
          template<Tvoid f(T t) called: t == 4
          >
          Is there a way to write a call to f(5), so that the output would be:
          template<Tvoid f(T t) called: t == 5
          Never mind the semantic accuracy or elegance (or lack thereof!) of
          what I wrote. If this is what we are aiming for, I suppose the
          question
          would be:
          >
          Is there a way to make the compiler generate its own instantiation,
          rather than use the explicit one that I provided? When asked this way,
          it would seem that the answer would be no, because if it generated its
          own instantiation, it would be a duplicate symbol, because mine
          already
          exists.
          >
          Still, one never knows if the Powers That Be thought of some clever
          reason to allow this, that mere mortals such as myself could not.
          That's why I'm asking.
          Now suppose you have some sort of container class called
          dweeblist that is filled with dweeb objects. A pointer to the
          current dweeb object is produced with member function current().
          You can define a function that applies a member function
          (which is passed as an argument) to all dweeb objects in dweeblist
          and then call this function for dweeblist dl like this:

          #include <iostream.h>

          class dweeb {
          public:
          void spin () {cout << "spinning!" << endl; }
          void dodge () {cout << "dodging!" << endl; }
          void feint () {cout << "feinting!" << endl; }
          };

          template<int szclass dweeblist {
          dweeb list [sz];
          int cursor;
          public:
          dweeblist () : cursor(0) {}
          void reset () { cursor = 0; }
          dweeb * current () { return &list [cursor]; }
          void next () { cursor++; }
          int end () { return cursor >= sz; }
          void apply (void (dweeb::* df) () ) {
          reset ();
          while ( !end() ) {
          (current ()->*df) ();
          next ();
          }
          }
          };

          void main () {
          dweeblist<7dl;
          dl.apply(&dweeb ::spin);
          dl.apply(&dweeb ::dodge);
          dl.apply(&dweeb ::feint);
          }

          Typically, the kind of function you'd want to apply()
          to every object in a list would be something like draw().
          for CAD.

          Pointers to members have fairly limited use, but they
          can be quite helpful when you want to delay the selection
          of a specific function until the program is running.

          C++ Inside & Out
          Bruce Eckel


          Comment

          • johnbrown105@hotmail.com

            #6
            Re: Template Specialisation

            On Nov 23, 12:51 pm, "Tadeusz B. Kopec" <tko...@NOSPAMP LEASElife.pl>
            wrote:
            On Fri, 23 Nov 2007 06:39:05 -0800, johnbrown105 wrote:
            Is it possible to force the compiler to use a generic template rather
            than a
            matching specialisation?
            >
            Consider the following:
            >
            ////////////////////////////////////////// template.cpp starts here
            >
            #include <iostream>
            #include <ostream>
            >
            template<class T>
            void f(T t)
            {
            std::cout << "template<T void f(T t) called: t == " << t
            << std::endl;
            }
            >
            template<void f<int>(int i)
            {
            std::cout << "specialisa tion void f<int>(int i) called: i == "
            << i << std::endl;
            }
            >
            void f(int j){
            std::cout << "overloaded void f(int j) called: j == "
            << j << std::endl;
            }
            >
            int main()
            {
            f(1); // simple function matches before template f<int>(2);
            // specialisation
            f<>(3); // no need to spell out <int>, because it *must* be int
            f('4'); // template matches - f<char>(char) return 0;
            }
            >
            ////////////////////////////////////////// template.cpp ends here
            >
            Is there a way to call f with an int parameter so that the generic f<T>
            is called instead of the f<intspecialisa tion?
            >
            f(3u) or f<unsigned>(3) would be OK?
            >
            --
            Tadeusz B. Kopec (tko...@NOSPAMP LEASElife.pl)

            Not really. An unsigned int is, of course, not the same as a signed
            int.
            Naturally, it would generate and call f(char). I want to find out if,
            even though I have provided f<int>(int), there was a way to make the
            compiler generate f(int) using the f<T>(int T) template. This function
            would, of course, be different from the one that I provided.

            As I said in my original post, I don't actually want to do this.
            Neither do
            I foresee a need to do it, so don't think too hard about it.

            Comment

            • johnbrown105@hotmail.com

              #7
              Re: Template Specialisation

              On Nov 23, 1:31 pm, "John Scheldroup" <johnscheldr... @comcast.net>
              wrote:
              <johnbrown...@h otmail.comwrote in messagenews:552 510ac-545a-4b28-880f-07a06b322b62@i1 2g2000prf.googl egroups.com...
              On Nov 23, 9:49 am, Matthias Buelow <m...@incubus.d ewrote:
              johnbrown...@ho tmail.com wrote:
              Is there a way to call f with an int parameter so that the generic
              f<Tis called instead of the f<intspecialisa tion?
              >
              There is no f<T>, a template is kind of a compiler macro, the compiler
              generates functions only if you instantiate a template (expand the
              macro, in other words).
              >
              I understand that. Consider the output of the program that I posted:
              >
              overloaded void f(int j) called: j == 1
              specialization void f<int>(int i) called: i == 2
              specialization void f<int>(int i) called: i == 3
              template<Tvoid f(T t) called: t == 4
              >
              Is there a way to write a call to f(5), so that the output would be:
              template<Tvoid f(T t) called: t == 5
              Never mind the semantic accuracy or elegance (or lack thereof!) of
              what I wrote. If this is what we are aiming for, I suppose the
              question
              would be:
              >
              Is there a way to make the compiler generate its own instantiation,
              rather than use the explicit one that I provided? When asked this way,
              it would seem that the answer would be no, because if it generated its
              own instantiation, it would be a duplicate symbol, because mine
              already
              exists.
              >
              Still, one never knows if the Powers That Be thought of some clever
              reason to allow this, that mere mortals such as myself could not.
              That's why I'm asking.
              >
              Now suppose you have some sort of container class called
              dweeblist that is filled with dweeb objects. A pointer to the
              current dweeb object is produced with member function current().
              You can define a function that applies a member function
              (which is passed as an argument) to all dweeb objects in dweeblist
              and then call this function for dweeblist dl like this:
              >
              #include <iostream.h>
              >
              class dweeb {
              public:
              void spin () {cout << "spinning!" << endl; }
              void dodge () {cout << "dodging!" << endl; }
              void feint () {cout << "feinting!" << endl; }
              >
              };
              >
              template<int szclass dweeblist {
              dweeb list [sz];
              int cursor;
              public:
              dweeblist () : cursor(0) {}
              void reset () { cursor = 0; }
              dweeb * current () { return &list [cursor]; }
              void next () { cursor++; }
              int end () { return cursor >= sz; }
              void apply (void (dweeb::* df) () ) {
              reset ();
              while ( !end() ) {
              (current ()->*df) ();
              next ();
              }
              }
              >
              };
              >
              void main () {
              dweeblist<7dl;
              dl.apply(&dweeb ::spin);
              dl.apply(&dweeb ::dodge);
              dl.apply(&dweeb ::feint);
              >
              }
              >
              Typically, the kind of function you'd want to apply()
              to every object in a list would be something like draw().
              for CAD.
              >
              Pointers to members have fairly limited use, but they
              can be quite helpful when you want to delay the selection
              of a specific function until the program is running.
              >
              C++ Inside & Out
              Bruce Eckel
              I'm not sure how this relates to my question. The reference to
              Bruce Eckel is interesting, as I am currently working through
              the chapter on templates in his "Thinking in C++ Vol. 2"

              Comment

              Working...