Static Member Function Template Specialization

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

    #1

    Static Member Function Template Specialization

    Hello everyone, thanks in advance for your help. I'm new to C++
    templates and have run into some issues using member function
    templates. I have a shared library containing templates that I'm
    trying to use from an executable, compile using gcc 4.1.2. Everything
    works fine until I try specializing one of the static member function
    templates in a non-template class. I have a feeling I'm messing up
    something obvious so before I post a bunch of code does the following
    look correct? Thanks.

    --- Shared Library (Arrays.h) ---

    namespace example {
    class Arrays {
    public:
    template<class Tstatic int compareItems(T *a1, T *a2, int length);
    protected:
    Arrays() {};
    };

    template<class Tint Arrays::compare Items(T *a1, T *a2, int length) {
    printf("Calling generic function.\n");
    return 1;
    }

    template<int Arrays::compare Items<char>(cha r *a1, char *a2, int
    length) {
    printf("Calling char specialization. \n");
    return 0;
    }
    }

  • =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=

    #2
    Re: Static Member Function Template Specialization

    On 2007-10-14 18:38, mike b wrote:
    Hello everyone, thanks in advance for your help. I'm new to C++
    templates and have run into some issues using member function
    templates. I have a shared library containing templates that I'm
    trying to use from an executable, compile using gcc 4.1.2. Everything
    works fine until I try specializing one of the static member function
    templates in a non-template class. I have a feeling I'm messing up
    something obvious so before I post a bunch of code does the following
    look correct? Thanks.
    >
    --- Shared Library (Arrays.h) ---
    >
    namespace example {
    class Arrays {
    public:
    template<class Tstatic int compareItems(T *a1, T *a2, int length);
    protected:
    Arrays() {};
    };
    >
    template<class Tint Arrays::compare Items(T *a1, T *a2, int length) {
    printf("Calling generic function.\n");
    return 1;
    }
    >
    template<int Arrays::compare Items<char>(cha r *a1, char *a2, int
    length) {
    printf("Calling char specialization. \n");
    return 0;
    }
    }
    I can see nothing wrong with it (except using printf and not including
    <stdio.h>). What error messages are you getting and how are you trying
    to use the function?

    --
    Erik Wikström

    Comment

    • Lance Diduck

      #3
      Re: Static Member Function Template Specialization

      On Oct 14, 12:38 pm, mike b <michaeljber... @gmail.comwrote :
      Hello everyone, thanks in advance for your help. I'm new to C++
      templates and have run into some issues using member function
      templates. I have a shared library containing templates that I'm
      trying to use from an executable, compile using gcc 4.1.2. Everything
      works fine until I try specializing one of the static member function
      templates in a non-template class. I have a feeling I'm messing up
      something obvious so before I post a bunch of code does the following
      look correct? Thanks.
      >
      --- Shared Library (Arrays.h) ---
      >
      namespace example {
      class Arrays {
      public:
      template<class Tstatic int compareItems(T *a1, T *a2, int length);
      protected:
      Arrays() {};
      >
      };
      >
      template<class Tint Arrays::compare Items(T *a1, T *a2, int length) {
      printf("Calling generic function.\n");
      return 1;
      >
      }
      >
      template<int Arrays::compare Items<char>(cha r *a1, char *a2, int
      length) {
      printf("Calling char specialization. \n");
      return 0;
      >
      >
      >
      }
      }- Hide quoted text -
      >
      - Show quoted text -
      Your specialization should be inside the example:Arrays class, not
      outside it.
      namespace example {
      class Arrays {
      public:
      template<class Tstatic int compareItems(T *a1, T *a2, int
      length);
      static int compareItems(ch ar*a1, char *a2, int
      length);
      };


      You cant add a new specialization once the class declaration is
      closed. If compareItems were a namespace level declaration, then you
      can reopen the namespace and add a new specialization later.
      Lance

      Comment

      • Gianni Mariani

        #4
        Re: Static Member Function Template Specialization

        mike b wrote:
        Hello everyone, thanks in advance for your help. I'm new to C++
        templates and have run into some issues using member function
        templates. I have a shared library containing templates that I'm
        trying to use from an executable, compile using gcc 4.1.2. Everything
        works fine until I try specializing one of the static member function
        templates in a non-template class. I have a feeling I'm messing up
        something obvious so before I post a bunch of code does the following
        look correct? Thanks.
        >
        --- Shared Library (Arrays.h) ---
        >
        namespace example {
        class Arrays {
        public:
        template<class Tstatic int compareItems(T *a1, T *a2, int length);
        protected:
        Arrays() {};
        };
        >
        template<class Tint Arrays::compare Items(T *a1, T *a2, int length) {
        printf("Calling generic function.\n");
        return 1;
        }
        >
        template<int Arrays::compare Items<char>(cha r *a1, char *a2, int
        length) {
        printf("Calling char specialization. \n");
        return 0;
        }
        }
        This below compiles fine and does what I think you expect. What problem
        are you having ?

        #include <cstdio>
        #include <iostream>

        namespace example {
        class Arrays {
        public:
        template<class Tstatic int compareItems(T *a1, T *a2, int length);
        Arrays() {};
        };

        template<class Tint Arrays::compare Items(T *a1, T *a2, int length) {
        std::printf("Ca lling generic function.\n");
        return 1;
        }

        template<int Arrays::compare Items<char>(cha r *a1, char *a2, int
        length) {
        std::printf("Ca lling char specialization. \n");
        return 0;
        }
        }

        int main()
        {
        std::cout << example::Arrays ::compareItems( (short*)0, (short*)0, 0
        ) << "\n";
        std::cout << example::Arrays ::compareItems( (char*)0, (char*)0, 0 )
        << "\n";
        }

        Comment

        • =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=

          #5
          Re: Static Member Function Template Specialization

          On 2007-10-14 20:16, Lance Diduck wrote:
          On Oct 14, 12:38 pm, mike b <michaeljber... @gmail.comwrote :
          >Hello everyone, thanks in advance for your help. I'm new to C++
          >templates and have run into some issues using member function
          >templates. I have a shared library containing templates that I'm
          >trying to use from an executable, compile using gcc 4.1.2. Everything
          >works fine until I try specializing one of the static member function
          >templates in a non-template class. I have a feeling I'm messing up
          >something obvious so before I post a bunch of code does the following
          >look correct? Thanks.
          >>
          >--- Shared Library (Arrays.h) ---
          >>
          >namespace example {
          >class Arrays {
          > public:
          > template<class Tstatic int compareItems(T *a1, T *a2, int length);
          > protected:
          > Arrays() {};
          >>
          >};
          >>
          >template<cla ss Tint Arrays::compare Items(T *a1, T *a2, int length) {
          > printf("Calling generic function.\n");
          > return 1;
          >>
          >}
          >>
          >template<int Arrays::compare Items<char>(cha r *a1, char *a2, int
          >length) {
          > printf("Calling char specialization. \n");
          > return 0;
          >>
          >>
          >>
          >}
          >}- Hide quoted text -
          >>
          >- Show quoted text -
          Your specialization should be inside the example:Arrays class, not
          outside it.
          namespace example {
          class Arrays {
          public:
          template<class Tstatic int compareItems(T *a1, T *a2, int
          length);
          static int compareItems(ch ar*a1, char *a2, int
          length);
          };
          Actually, what you are suggesting is not a specialisation, but declaring
          a non-parametrised function taking care of the special case. Which, to
          my knowledge, will work just as well but there are probably some subtle
          details that make specialised parametrised functions different from
          normal functions.

          --
          Erik Wikström

          Comment

          • Neelesh Bodas

            #6
            Re: Static Member Function Template Specialization

            On Oct 14, 11:16 pm, Lance Diduck <lancedid...@ny c.rr.comwrote:
            On Oct 14, 12:38 pm, mike b <michaeljber... @gmail.comwrote :
            Your specialization should be inside the example:Arrays class, not
            outside it.
            namespace example {
            class Arrays {
            public:
            template<class Tstatic int compareItems(T *a1, T *a2, int
            length);
            static int compareItems(ch ar*a1, char *a2, int
            length);
            };
            IIRR, a template specialization will always start with the word
            "template". Hence, the above (non-template) function is surely not a
            specialization of the template function.

            >
            You cant add a new specialization once the class declaration is
            closed.
            14.7.3(2) says:
            "An explicit specialization of a member function, member class or
            static data member of a class template shall be declared in the
            namespace of which the class template is a member"

            Which means that new specializations can be added in the same
            namespace.

            -N

            Comment

            • mike b

              #7
              Re: Static Member Function Template Specialization

              On Oct 14, 2:16 pm, Lance Diduck <lancedid...@ny c.rr.comwrote:
              On Oct 14, 12:38 pm, mike b <michaeljber... @gmail.comwrote :
              >
              Hello everyone, thanks in advance for your help. I'm new to C++
              templates and have run into some issues using member function
              templates. I have a shared library containing templates that I'm
              trying to use from an executable, compile using gcc 4.1.2. Everything
              works fine until I try specializing one of the static member function
              templates in a non-template class. I have a feeling I'm messing up
              something obvious so before I post a bunch of code does the following
              look correct? Thanks.
              >
              --- Shared Library (Arrays.h) ---
              >
              namespace example {
              class Arrays {
              public:
              template<class Tstatic int compareItems(T *a1, T *a2, int length);
              protected:
              Arrays() {};
              >
              };
              >
              template<class Tint Arrays::compare Items(T *a1, T *a2, int length) {
              printf("Calling generic function.\n");
              return 1;
              >
              }
              >
              template<int Arrays::compare Items<char>(cha r *a1, char *a2, int
              length) {
              printf("Calling char specialization. \n");
              return 0;
              >
              }
              }- Hide quoted text -
              >
              - Show quoted text -
              >
              Your specialization should be inside the example:Arrays class, not
              outside it.
              namespace example {
              class Arrays {
              public:
              template<class Tstatic int compareItems(T *a1, T *a2, int
              length);
              static int compareItems(ch ar*a1, char *a2, int
              length);
              };
              >
              You cant add a new specialization once the class declaration is
              closed. If compareItems were a namespace level declaration, then you
              can reopen the namespace and add a new specialization later.
              Lance
              I tried this but it doesn't automatically call my specialization. Do
              I need to call overloaded implementations of the function from inside
              the generic implementation? So basically don't use specialization at
              all, use overloading from within the single generic implementation?

              Comment

              • mike b

                #8
                Re: Static Member Function Template Specialization

                On Oct 14, 2:16 pm, Gianni Mariani <gi4nos...@mari an.wswrote:
                mike b wrote:
                Hello everyone, thanks in advance for your help. I'm new to C++
                templates and have run into some issues using member function
                templates. I have a shared library containing templates that I'm
                trying to use from an executable, compile using gcc 4.1.2. Everything
                works fine until I try specializing one of the static member function
                templates in a non-template class. I have a feeling I'm messing up
                something obvious so before I post a bunch of code does the following
                look correct? Thanks.
                >
                --- Shared Library (Arrays.h) ---
                >
                namespace example {
                class Arrays {
                public:
                template<class Tstatic int compareItems(T *a1, T *a2, int length);
                protected:
                Arrays() {};
                };
                >
                template<class Tint Arrays::compare Items(T *a1, T *a2, int length) {
                printf("Calling generic function.\n");
                return 1;
                }
                >
                template<int Arrays::compare Items<char>(cha r *a1, char *a2, int
                length) {
                printf("Calling char specialization. \n");
                return 0;
                }
                }
                >
                This below compiles fine and does what I think you expect. What problem
                are you having ?
                >
                #include <cstdio>
                #include <iostream>
                >
                namespace example {
                class Arrays {
                public:
                template<class Tstatic int compareItems(T *a1, T *a2, int length);
                Arrays() {};
                >
                };
                >
                template<class Tint Arrays::compare Items(T *a1, T *a2, int length) {
                std::printf("Ca lling generic function.\n");
                return 1;
                >
                }
                >
                template<int Arrays::compare Items<char>(cha r *a1, char *a2, int
                length) {
                std::printf("Ca lling char specialization. \n");
                return 0;
                >
                }
                }
                >
                int main()
                {
                std::cout << example::Arrays ::compareItems( (short*)0, (short*)0, 0
                ) << "\n";
                std::cout << example::Arrays ::compareItems( (char*)0, (char*)0, 0 )
                << "\n";
                >
                }
                The problem only occurs when code is separated into multiple binaries,
                a shared lib and executable, with multiple users in the app.

                Comment

                • Gianni Mariani

                  #9
                  Re: Static Member Function Template Specialization

                  mike b wrote:
                  On Oct 14, 2:16 pm, Gianni Mariani <gi4nos...@mari an.wswrote:
                  ....
                  The problem only occurs when code is separated into multiple binaries,
                  a shared lib and executable, with multiple users in the app.

                  Are definitions of all template functions in every compilation unit ?
                  (i.e. included into every binary's source in question ?) If not, that's
                  your problem.

                  Comment

                  • mike b

                    #10
                    Re: Static Member Function Template Specialization

                    On Oct 14, 6:13 pm, Gianni Mariani <gi4nos...@mari an.wswrote:
                    mike b wrote:
                    On Oct 14, 2:16 pm, Gianni Mariani <gi4nos...@mari an.wswrote:
                    ...
                    The problem only occurs when code is separated into multiple binaries,
                    a shared lib and executable, with multiple users in the app.
                    >
                    Are definitions of all template functions in every compilation unit ?
                    (i.e. included into every binary's source in question ?) If not, that's
                    your problem.
                    I defined my entire template class in the header file (.h) so it
                    should be making it into every compilation unit. Is there something
                    aside from that I need to do?

                    Comment

                    • mike b

                      #11
                      Re: Static Member Function Template Specialization

                      On Oct 14, 12:38 pm, mike b <michaeljber... @gmail.comwrote :
                      Hello everyone, thanks in advance for your help. I'm new to C++
                      templates and have run into some issues using member function
                      templates. I have a shared library containing templates that I'm
                      trying to use from an executable, compile using gcc 4.1.2. Everything
                      works fine until I try specializing one of the static member function
                      templates in a non-template class. I have a feeling I'm messing up
                      something obvious so before I post a bunch of code does the following
                      look correct? Thanks.
                      >
                      --- Shared Library (Arrays.h) ---
                      >
                      namespace example {
                      class Arrays {
                      public:
                      template<class Tstatic int compareItems(T *a1, T *a2, int length);
                      protected:
                      Arrays() {};
                      >
                      };
                      >
                      template<class Tint Arrays::compare Items(T *a1, T *a2, int length) {
                      printf("Calling generic function.\n");
                      return 1;
                      >
                      }
                      >
                      template<int Arrays::compare Items<char>(cha r *a1, char *a2, int
                      length) {
                      printf("Calling char specialization. \n");
                      return 0;
                      >
                      }
                      }
                      Sincere thanks to everyone who responded, the problem has been
                      solved. The issue it seems is that I was defining my member
                      specializations in the header but only a declaration for the
                      specialization is allowed in the header, the actual implementation
                      must go in the implementation file, .cpp. So here is the change to
                      make the code work:

                      --- Arrays.h ---

                      namespace example {
                      class Arrays : public Object {
                      public:
                      template<class Tstatic int compareItems(co nst T a1[], const
                      T a2[], const int length);
                      };

                      // I was defining the function here but only the declaration goes here
                      template<int Arrays::compare Items(const char a1[], const char a2[],
                      const int length);

                      template<class Tint compareItems(co nst T a1[], const T a2[], const
                      int length) {
                      // Generic implementation goes here.
                      }
                      }


                      --- Arrays.cpp ---

                      // This was in the header file before and was causing the problems,
                      moving it here solved it.
                      template<int hydro::Arrays:: compareItems(co nst char a1[], const char
                      a2[], const int length) {
                      return strncmp(a1, a2, length);
                      }

                      --- END ---

                      Comment

                      • Gianni Mariani

                        #12
                        Re: Static Member Function Template Specialization

                        mike b wrote:
                        ....
                        Sincere thanks to everyone who responded, the problem has been
                        solved. The issue it seems is that I was defining my member
                        specializations in the header but only a declaration for the
                        specialization is allowed in the header, the actual implementation
                        must go in the implementation file, .cpp.
                        Sounds strange. What errors were you getting ?

                        Comment

                        • mike b

                          #13
                          Re: Static Member Function Template Specialization

                          On Oct 16, 3:45 pm, Gianni Mariani <gi4nos...@mari an.wswrote:
                          mike b wrote:
                          >
                          ...
                          >
                          Sincere thanks to everyone who responded, the problem has been
                          solved. The issue it seems is that I was defining my member
                          specializations in the header but only a declaration for the
                          specialization is allowed in the header, the actual implementation
                          must go in the implementation file, .cpp.
                          >
                          Sounds strange. What errors were you getting ?
                          I was getting errors about my specialization being defined multiple
                          times. This was with GCC 4.

                          Comment

                          • Gianni Mariani

                            #14
                            Re: Static Member Function Template Specialization

                            mike b wrote:
                            On Oct 16, 3:45 pm, Gianni Mariani <gi4nos...@mari an.wswrote:
                            >mike b wrote:
                            >>
                            >...
                            >>
                            >>Sincere thanks to everyone who responded, the problem has been
                            >>solved. The issue it seems is that I was defining my member
                            >>specializatio ns in the header but only a declaration for the
                            >>specializatio n is allowed in the header, the actual implementation
                            >>must go in the implementation file, .cpp.
                            >Sounds strange. What errors were you getting ?
                            >
                            I was getting errors about my specialization being defined multiple
                            times. This was with GCC 4.

                            Declare the template as "inline" as see if you get the same errors.

                            Comment

                            Working...