Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. C++ - Static templated method inside a class

C++ - Static templated method inside a class

Scheduled Pinned Locked Moved C / C++ / MFC
c++helpcsharpasp-netquestion
9 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    phil o
    wrote on last edited by
    #1

    So, I finally decided to dive into C++ world, trying to adapt some C# code I've been working on lately. So here's what I have. bin.h file:

    #pragma once

    namespace Maths {

    class Bin
    {
    public:
    template static const T GetMask(int);
    };

    }

    bin.cpp file:

    #include "bin.h"

    namespace Maths {

    template const T Bin::GetMask(int count) {
    return (T)0; // Fake implementation
    }

    }

    This compiles just fine. However, in the same console project, when I write:

    #include "bin.h"

    using namespace Maths;

    int main() {
    unsigned char value = Bin::GetMask<unsigned char>(0);
    }

    I get a nasty LNK2019 linkage error on compilation:

    Error LNK2019 unresolved external symbol "public: static unsigned char const __cdecl Maths::Bin::GetMask(int)" (??$GetMask@E@Bin@Maths@@SA?BEH@Z) referenced in function "int __cdecl main(void)" (?main@@YAXXZ)

    In the Bin class, I have a couple of other (non-generic) methods, which I can use just fine. I suspect a problem with static templated methods specifically, but I can't understand the core problem. Maybe I just try to do something which is not possible (using a static generic method), but I cannot figure out why it would not be possible. Anyone could give me a hint on this?

    "I'm neither for nor against, on the contrary." John Middle

    L 1 Reply Last reply
    0
    • P phil o

      So, I finally decided to dive into C++ world, trying to adapt some C# code I've been working on lately. So here's what I have. bin.h file:

      #pragma once

      namespace Maths {

      class Bin
      {
      public:
      template static const T GetMask(int);
      };

      }

      bin.cpp file:

      #include "bin.h"

      namespace Maths {

      template const T Bin::GetMask(int count) {
      return (T)0; // Fake implementation
      }

      }

      This compiles just fine. However, in the same console project, when I write:

      #include "bin.h"

      using namespace Maths;

      int main() {
      unsigned char value = Bin::GetMask<unsigned char>(0);
      }

      I get a nasty LNK2019 linkage error on compilation:

      Error LNK2019 unresolved external symbol "public: static unsigned char const __cdecl Maths::Bin::GetMask(int)" (??$GetMask@E@Bin@Maths@@SA?BEH@Z) referenced in function "int __cdecl main(void)" (?main@@YAXXZ)

      In the Bin class, I have a couple of other (non-generic) methods, which I can use just fine. I suspect a problem with static templated methods specifically, but I can't understand the core problem. Maybe I just try to do something which is not possible (using a static generic method), but I cannot figure out why it would not be possible. Anyone could give me a hint on this?

      "I'm neither for nor against, on the contrary." John Middle

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      The Maths namespace does not contain a definition/declaration of Bin::GetMask(int); only one of Bin::GetMask(int);. Just remove the <unsigned char> piece and it should be fine.

      P 2 Replies Last reply
      0
      • L Lost User

        The Maths namespace does not contain a definition/declaration of Bin::GetMask(int); only one of Bin::GetMask(int);. Just remove the <unsigned char> piece and it should be fine.

        P Offline
        P Offline
        phil o
        wrote on last edited by
        #3

        Thank you Richard for answering. However, if I try to remove the <unsigned char> piece (namely: unsigned char value = Bin::GetMask(0);), the editor itself complains about the fact that no instance of function template "Maths::Bin::GetMask" matches the argument list. Moreover, the Bin::GetMask(int) is actually declared in Maths namespace. Problem seems to be with the .cpp part: the editor/IDE can see the definition of the generic method (since the editor does not complain when I try to use it, and the object explorer clearly displays the method with correct signature), but, on compilation, the linker cannot make a link to the actual implementation. How can I correctly declare a static, generic method inside a non-generic class, then? Thanks for your time :)

        "I'm neither for nor against, on the contrary." John Middle

        L 1 Reply Last reply
        0
        • L Lost User

          The Maths namespace does not contain a definition/declaration of Bin::GetMask(int); only one of Bin::GetMask(int);. Just remove the <unsigned char> piece and it should be fine.

          P Offline
          P Offline
          phil o
          wrote on last edited by
          #4

          Anyway, I found the issue. I cannot implement a template method in the .cpp file, like I did with other non generic methods. I moved the implementation of the generic method in the .h header file, and now everything is ok. I guess I have to dig deeper in the translation unit concept :)

          "I'm neither for nor against, on the contrary." John Middle

          CPalliniC L 2 Replies Last reply
          0
          • P phil o

            Anyway, I found the issue. I cannot implement a template method in the .cpp file, like I did with other non generic methods. I moved the implementation of the generic method in the .h header file, and now everything is ok. I guess I have to dig deeper in the translation unit concept :)

            "I'm neither for nor against, on the contrary." John Middle

            CPalliniC Offline
            CPalliniC Offline
            CPallini
            wrote on last edited by
            #5

            Yes, that's it. Template method definitions should be in header files.

            In testa che avete, signor di Ceprano?

            1 Reply Last reply
            0
            • P phil o

              Thank you Richard for answering. However, if I try to remove the <unsigned char> piece (namely: unsigned char value = Bin::GetMask(0);), the editor itself complains about the fact that no instance of function template "Maths::Bin::GetMask" matches the argument list. Moreover, the Bin::GetMask(int) is actually declared in Maths namespace. Problem seems to be with the .cpp part: the editor/IDE can see the definition of the generic method (since the editor does not complain when I try to use it, and the object explorer clearly displays the method with correct signature), but, on compilation, the linker cannot make a link to the actual implementation. How can I correctly declare a static, generic method inside a non-generic class, then? Thanks for your time :)

              "I'm neither for nor against, on the contrary." John Middle

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              phil.o wrote:

              the Bin::GetMask<T>(int) is actually declared in Maths namespace.

              I don't see it anywhere, unless that is somehow implied by template static const T GetMask(int);. Hmm, I though I understood templates.

              1 Reply Last reply
              0
              • P phil o

                Anyway, I found the issue. I cannot implement a template method in the .cpp file, like I did with other non generic methods. I moved the implementation of the generic method in the .h header file, and now everything is ok. I guess I have to dig deeper in the translation unit concept :)

                "I'm neither for nor against, on the contrary." John Middle

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #7

                phil.o wrote:

                the translation unit concept

                The only reason for creating header files is when you have a set of common definitions that need to be shared by multiple translation units. If you only have a single .cpp file then all the definitions can safely be put in there. The #include statement is recognised by the preprocessor which reads all the include files and creates a new text file containing all the included code followed by the user written C/C++ code, and passes that new composite to the actual compiler.

                P 1 Reply Last reply
                0
                • L Lost User

                  phil.o wrote:

                  the translation unit concept

                  The only reason for creating header files is when you have a set of common definitions that need to be shared by multiple translation units. If you only have a single .cpp file then all the definitions can safely be put in there. The #include statement is recognised by the preprocessor which reads all the include files and creates a new text file containing all the included code followed by the user written C/C++ code, and passes that new composite to the actual compiler.

                  P Offline
                  P Offline
                  phil o
                  wrote on last edited by
                  #8

                  I have learnt it the hard way :) This explains why everything was fine as far as the editor/IDE were concerned, and why the issue only occurred on the linking phase. That's quite confusing for a beginner.

                  "I'm neither for nor against, on the contrary." John Middle

                  L 1 Reply Last reply
                  0
                  • P phil o

                    I have learnt it the hard way :) This explains why everything was fine as far as the editor/IDE were concerned, and why the issue only occurred on the linking phase. That's quite confusing for a beginner.

                    "I'm neither for nor against, on the contrary." John Middle

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #9

                    phil.o wrote:

                    quite confusing for a beginner.

                    and sometimes for the rest of us.

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups