You can't put definitions of template functions in separate source files. The compiler needs them at the point of usage in order to figure out how to compile the usage.
Take all the contents of Behaviors.cpp and move them into Behaviors.h. If you want, you can #include "Behaviors.cpp" at the end of the header.
Including Behaviors.cpp resulted in a ton of recurse errors. I ended up moving the function definition for MacroBehavior::program from Behaviors.cpp to Behaviors.h and that fixed the problem.
This is bugging me though. There's got to be a better way. I read that you can instantiate the template class in the header file where the definition resides and that should work but I cant find the appropriate syntax for this. Here is the code for map_item class for anyone interested in trying.
in Behaviors.h after definition of the template. The compiler accepts this but I still get the linker errors. I dont know how the ellipsis figures into this as well.
You can instantiate a template explicitly, but you'll have to make an explicit instantiation for every different template parameter combination you use. For example, if you were implementing a map<K, V> and your program used map<std::string, int>, map<std::string, double, and map<int, double>, you'd need to explicitly instantiate each of those.
This is generally not done because it's more trouble than it's worth.
The only reason I am using the template is I thought it was a requirement to use variadic functions. I was not successful in converting the member function "MacroBehavior::program" into one that takes unknown multiple number of parameters without the use of the template ( unless I use an std::initializer). So there only really is one parameter type that needs instantiated and that's "std::shared_ptr<map_item>".
Is there a solution that does not involve using a variadic template for functions taking multlpe unknown parameter types?
If not, what would be the syntax of template instantiation for that one parameter type?
So there only really is one parameter type that needs instantiated and that's "std::shared_ptr<map_item>".
No, because the function that takes 1 std::shared_ptr<map_item> is of a different type from the one that takes 2 and from the one that takes 3.
You could use a C variadic function, but variadic template functions were introduced because C variadic functions are so error-prone and dangerous to use.
I see. I think I may need to implement another variadic function but this time it needs to live in the cpp file because I run into some errors if the definition is in the header file. It works fine if the definition is separated from the declaration. I may only need 1 to 3 arguments to the function. I am still working on the details. Just in case the way I understand this is that I need to instantiate templates with one, then two, then three parameters. For the case of std::shared_ptr<map_item> then it would be :
this time it needs to live in the cpp file because I run into some errors if the definition is in the header file. It works fine if the definition is separated from the declaration.
You mentioned that you get errors from recursion. Did you try removing the #include "Behaviors.h" from Behaviors.cpp when including it in the header?
I did try that after I read your suggestion. However, it results in a ton of multiple definitions for functions and classes in Behaviors.cpp. Probably bechase Behaviors.h is included by multiple files. Is there a solution?
If Behaviors.cpp only includes template definitions there should be no duplicate definitions, because the compiler treats template definitions the same as if they were inline.
I created a Variadic.cpp that only has the definition of Behavior::operator()(Behavior::run_type, Behavior::result_type, ArgsV ...). I put in #include Variadic.cpp at the bottom of Behaviors.h. Then in Variadic.cpp I put at the top #include Behaviors.h. The result is :
1 2 3 4 5 6 7
Variadic.cpp:9:56: error: redefinition of ‘std::shared_ptr<map_item> Behavior::operator()(Behavior::run_type, Behavior::result_type, ArgsV ...)’
template <typename ...ArgsV> std::shared_ptr<map_item> Behavior::operator()(run_type a, result_type b, ArgsV... a_args){
In file included from Behaviors.h:479:0,
from Variadic.cpp:7:
Variadic.cpp:9:56: error: ‘std::shared_ptr<map_item> Behavior::operator()(Behavior::run_type, Behavior::result_type, ArgsV ...)’ previously declared here
template <typename ...ArgsV> std::shared_ptr<map_item> Behavior::operator()(run_type a, result_type b, ArgsV... a_args){
I am going to investigate the dependencies of the headers in my project. I just read last night that headers should be independently compileable. Maybe after I look into that, this solution might work?