Thread: Linker Errors with Templates

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    24

    Linker Errors with Templates

    So, I'll just toss some example code at you to start:

    This is the struct and its constructor:

    Code:
    template <class type_s> struct task {
        double time;
        void (*task)(type_s);
        type_s args;
    };
    
    template <class type_s> void new_task(double time, void (*function)(type_s), type_s arg_struct = NULL)
    {    
        // Instance initialization
        task<type_s>* task_p = malloc(sizeof(task<type_s>));
        task_p->time = time;
        task_p->task = function;
        task_p->args = arg_struct;
        
        // Placing request on the queue
        queue.push(task_p);
    }
    This is the .h:
    Code:
    #include <iostream>
    template <class type_s> void new_task(double,void(*)(type_s),type_s arg_struct = NULL);
    And this is the sample program:
    Code:
    typedef struct test{
        int x;
        int y;
    } test_s;
    
    
    void func_1(test_s argument)
    {
        int x = argument.x;
        int y = argument.y;
        cout<< x << y << "\n\n";
    }
    
    int main()
    {    
        test_s t;
        t.x = 2;
        t.y = 3;
            
        new_task(30,&func_1,t);
    }
    So this is what's happening: undefined reference to `void new_task<test>(double, void (*)(test), test)'

    Why is it happening that way, as far as you can tell? Did I template something incorrectly?

  2. #2
    Moderately Rabid Decrypt's Avatar
    Join Date
    Feb 2005
    Location
    Milwaukee, WI, USA
    Posts
    300
    I think the problem is that you are not including the template files correctly; you have to include files differently with templates than with other classes. You have two options:

    Either #include "templatefile.cpp" in the sample program, or

    Put the implementation of your templated class in the header file, and include that in the sample (client) program.

    [edit]I think you might be able to #include "templatewhatever.cpp" inside the template header, but I'm not sure. I'lll try it out and let you know.[/edit]
    [edit^2]Can't try it out now; can't telnet to school. Maybe later. [/edit]
    Last edited by Decrypt; 10-20-2006 at 06:19 PM.
    There is a difference between tedious and difficult.

  3. #3
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    The way you are declaring the template shouldn't cause this error. Doublecheck the command line you use for linking.
    Callou collei we'll code the way
    Of prime numbers and pings!

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> I think you might be able to #include "templatewhatever.cpp" inside the template header,
    Yeah, often people will include the cpp file at the bottom of the header to avoid linker errors.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    24
    So, am I hearing that I should put the templates in their own header file, or put them in a separate .cpp and include that, or that I should include the templated functions in the existing .h?

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    24
    Any combination of those doesn't work, unless I'm still not doing it right. Is there a sample? Just show me how to do it in relation to what I posted and I'll try it.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The simplest way to do it is to put all templated code inside a header file and none in a source file.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    24
    Including the templated stuff I want kept private? Also, what about stuff in the source referencing the templated functions and objects? There's a lot more code to this than I posted up...

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Templated functions and classes are just that, templates. Even the source implementation is just a template. It works differently depending on what type is passed to it. The compile needs to compile that code for each type that is used, but it cannot really know which type is being used if all it has is a source file with implementation. When you put the implementation in the header file, then the code is compiled when you are compiling the source file that actually uses the template, and at that point the compiler knows what type is being used.

    Code that just uses templated functions or classes can remain in source files that just include the header with the template functions.

    http://www.parashift.com/c++-faq-lit...html#faq-35.12

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    24
    Ok... following the articles' (which I read and now fully understand) instructions, I "plunked" my template code into the .h and took it out from the .cpp

    The .h includes the .cpp, the .cpp includes the .h, and the main program includes the .h

    And it still has the same linking issue. Dang. This is getting really old... Unless there's a different way to declare the template in the header, as far as I know I've done everything right. The main program can see the .h, can see the template, and should be able to construct a function...

    There's also still the issue of the templated struct that I don't want to have as user-visible, but it needs to be made from the same types that the function can see. Where should that go?

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The whole "put the code in the header" solution was just a guess as it is a common cause of undefined reference linker errors.

    So does it work if you just put everything in the header file?

    >> There's also still the issue of the templated struct that I don't want to have as user-visible
    Tough? There isn't a really good solution unless you know what types will be used with the struct.

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    24
    Not at all. Linker Errors abound, for every single call.

    However, having the main include the .cpp makes it all work!

    Now how can I keep those thing private that I want kept private?
    Last edited by LPP; 10-20-2006 at 07:35 PM.

  13. #13
    Registered User
    Join Date
    Sep 2006
    Posts
    24
    Ok, so, when I said it all worked, now it's kinda not. Because of it all being in the .cpp, for some reason, it is saying that every global variable in the .cpp (except for the templates) are defined twice, and Dev-C++ won't tell me where.

  14. #14
    Moderately Rabid Decrypt's Avatar
    Join Date
    Feb 2005
    Location
    Milwaukee, WI, USA
    Posts
    300
    >Now how can I keep those thing private that I want kept private?

    You can't, if you mean private as in your client can't see your implementation. A template isn't source code like a normal implementation. It's a template for the complier to create source code for you and compile it when the client uses it. As I understand it, when the client creates code using your template, the compiler fills in the code, substituting the type they used wherever it should go. It then compiles the resulting code.

    You can't precompile the template code, then send the object code along to the client to use. They get to see the entire implementation of your template. It's just the way it is. :shrug:

    If including the .cpp works, great. I usually just put it all in the header and include that in the client file.

    (btw, this is just how I understand it, but I haven't been working with templates long. If any of the above is incorrect, please let me know. I don't have time now to read that link. Sorry if any mistakes would have been cleared up there.)
    There is a difference between tedious and difficult.

  15. #15
    Registered User
    Join Date
    Sep 2006
    Posts
    24
    I meant private as in hidden code-wise, public-vs-private etc., and it's not working. I'll try the stuff again, but... -yawn-

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Templates + ref to pointer + linker error.
    By Sparrowhawk in forum C++ Programming
    Replies: 8
    Last Post: 05-18-2009, 04:06 PM
  2. Linker errors on Winsock2 functions
    By ShadowMetis in forum C++ Programming
    Replies: 2
    Last Post: 11-20-2004, 11:19 PM
  3. help, linker errors when adding library file to project
    By ngcfan525 in forum C++ Programming
    Replies: 1
    Last Post: 03-09-2003, 02:27 PM
  4. MSVis-Studio C++ libraries and linker errors
    By kellydj in forum Windows Programming
    Replies: 10
    Last Post: 03-12-2002, 02:03 PM
  5. Linker errors with simple static library
    By Dang in forum Windows Programming
    Replies: 5
    Last Post: 09-08-2001, 09:38 AM