+ 2

Template instantiation with different project | Base derived class

Here code below: https://www.sololearn.com/en/compiler-playground/c4klNA8CnhM6 This code compiles fine and no issue. Issue arises when baseT class and derivedT class are part of different project. Due to this separation, setSlot method which is templated will not be defined by compiler as different project has this method usage. Now when derived class related project is build, it fails to find this method while linking with base class project dll. How to avoid this issue? https://sololearn.com/compiler-playground/c4klNA8CnhM6/?ref=app

9th Dec 2024, 11:19 AM
Ketan Lalcheta
Ketan Lalcheta - avatar
14 Answers
+ 1
Seeing the more-explicit source code really helped. I assume <class t> is a typo, and is actually <class T>. Conventionally, common.h should be common.hpp. If it contains templates, it is incompatible with C. ----- I see only two solutions for you. Neither is very elegant in my opinion, and it exposes some of my personal disdain for C++. This is what I would do. Declare the add function as inline. In this way, add() is no longer a function symbol that causes conflict in the linker. // common.h template <class T> inline void add(T a, T b) { return a + b; } Of course, inline makes a larger executable that could be a problem in some cases. The other solution is to pre-declare in common.h each type of add() that you might use. It's very ugly! // Definition for specific types template <class T> void add(T a, T b) { return a + b; } // Explicit instantiations template void add<int>(int, int); template void add<float>(float, float);
15th Dec 2024, 11:46 AM
Brian
Brian - avatar
+ 3
It sounds like one of the projects is missing the template definition. Template definitions are typically placed in header files. Templates are processed by the compiler, not the linker. (The linker is what links references to dlls). Both projects should be including the template header file wherever the template is used.
9th Dec 2024, 2:15 PM
Brian
Brian - avatar
+ 3
Yes, that situation would cause redefinition error. A common way to avoid redefinition is to use preprocessor directives in each header file that check for prior definition of a unique symbol defined in the header. It looks like this: #ifndef HEADER_FILE_NAME #define HEADER_FILE_NAME // Entire header file content #endif // HEADER_FILE_NAME Some C++ compilers have a convenient #pragma option that handles this automatically if you place it at the beginning of every header file: #pragma once
10th Dec 2024, 7:17 AM
Brian
Brian - avatar
+ 2
Ketan Lalcheta it's puzzling to see that you got opposite results. What happens when you use the standard #ifndef/#endif approach?
13th Dec 2024, 7:28 AM
Brian
Brian - avatar
+ 2
I misunderstood, expecting that common.h held a prototype declaration for add(), not the function definition itself. As you have found, it is problematic when you put code into header files (other than macros). Function code should be in a .cpp file so that it has its own global scope.
13th Dec 2024, 11:54 PM
Brian
Brian - avatar
+ 1
Sounds good Brian I have a query about redefiniton of function. Suppose, I have a header file a.h in solution A which has function defined in header itself. Now, another solution B has two files b.h and c.h and both of these includes a.h. . does this not mean solution B has two definition of header function (one via b.h and other via c.h ) causing redefinition error?
10th Dec 2024, 5:16 AM
Ketan Lalcheta
Ketan Lalcheta - avatar
+ 1
Please, let us sharpen this point in question. Earlier you mentioned that common.h has the function defined as: void add() {} Instead, a function prototype for add() in common.h should look like: void add(); And then in a .cpp file, there should be: void add() {} Is that how it really appears?
14th Dec 2024, 10:52 AM
Brian
Brian - avatar
0
Hi Brian I observed very different outcome. I have four files like Header1.h , Header2.h , Common.h and Source.cpp All three header files have #pragma once defined at the start of the header file Header1.h and Header2.h includes Common.h Source.cpp includes both Header1.h and Header2.h Common.h has function defined as void add() {} Compiling this solution works and builds successfully. To my surprise, It still compiles successfully even though I remove the pragma statements. Why it works without pragma protection?
10th Dec 2024, 4:17 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
0
Scenario 2: I have four files like Common.h , Source.cpp and Source2.cpp Common.h file has #pragma once defined at the start of the header file and has one function defined as void add() {} Common.h is included in Source.cpp and Source2.cpp This set up fails to compile as Add function is defined in two units Source.obj and Source2.obj
10th Dec 2024, 4:37 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
0
Scenario 2 is I am damn sure that will not be protected by either IFNDEF or pragma Scenario 1 is very weird and should happen without guards. It works with or without pragma and ifndef
13th Dec 2024, 2:33 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
0
Yeah. Correct. Function definition in .cxx files. With this, I have my initial problem causing me build issue. That is , template function declaration in header and definition in cpp file. This project is built first. Now, other project includes header only and could not find definition causing build issue
14th Dec 2024, 3:58 AM
Ketan Lalcheta
Ketan Lalcheta - avatar
0
Let me do it again as below: Scenario 1 : Project1: common.h template<class t> void add(T a,T b); common.cpp: template<class t> void add(T a,T b) {return a+b;} Project1 is build independently no issue. Project2: main.cpp: includes common.h calls add(1,2) This project 2 fails to compile as template definition is not in header file. If I move definition from common.cpp to common.h, it works. However, moving definition to common.cpp fails in different scenario as discussed below: Scenario 2 : Project1: common.h template<class t> void add(T a,T b) {return a+b;} Project1 is build independently no issue. Project2: test1.cpp: includes common.h calls add(1,2) test2.cpp: includes common.h calls add(3,4) This fails to compile project2 as it finds add function definition in both test1.obj and test2.obj (from common.h) All these scenarios tried with #pragma once and #ifndef for common.h , but error remains as it is.
15th Dec 2024, 5:54 AM
Ketan Lalcheta
Ketan Lalcheta - avatar
0
Thanks @Brian
15th Dec 2024, 2:52 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
0
You're welcome, Ketan Lalcheta
15th Dec 2024, 6:18 PM
Brian
Brian - avatar