0

I faced with some compilation issues, here is details:

Lets say I have a declared of some data structure my_data_struct<typename T>. The reason I use templates here is I want my data structure to be able to work with any data type (Like std::stack or std::vector do)

In that case, if I don't know the final types it will be used for, I must define and declare my structure in one file.

Lets say then, I have couple of other libs (divided by .h declaration and .cpp definition). Each of them use my_data_struc.

Finally, lets say I have main.cpp file where "all comes together" with #include's.

How could I get compile my program?

If I will compile my cpp files separately to object files, and will try to link them togather, I will receive multiple definition of error, because my_data_struct will be defined couple of times...

The only way I realize, is to move definitions of my libs to its declaration (.h) files and then just compile the main.cpp all at once. But, is it the right way to compile programs like that? Or is there is any better way how to build and compile such stuff?

I didn't find any best practices of how to proceed with it...

Thanks in advice.

UPD:

Well, while creating example, I figured out that the actual issues is caused not by template class, but by non template functions that exists beside the class in the same namespace:

//mydatastruct.h
#ifndef MYSTRUCT
#define MYSTRUCT

namespace G{
    template<typename T>
    class my_data_struct{
        public: 
        my_data_struct(){};
        ~my_data_struct(){};
        int do_something(int a){ return a; };
        //...
    };

    int test(int b){ return 2; };
}

#endif
// a.h
#ifndef A_H
#define A_H

#include "mydatastruct.h"

class A{
    public:
    A();
    ~A();
};

#endif

// a.cpp
#include "a.h"
A::A(){}
A::~A(){}
// main.cpp
#include "a.h"
int main(){ return 0; }

Compiling:

g++ -c a.cpp -o a.o
g++ -c main.cpp -o main.o
g++ a.o main.o -o main.exe

And the actual error is:

main.o:main.cpp:(.text+0x0): multiple definition of `G::test(int)'
a.o:a.cpp:(.text+0x0): first defined here
Illia Moroz
  • 343
  • 1
  • 2
  • 13
  • @HolyBlackCat my question is not about "How to compile template classes", but how to proceed with "multiple definition of" error, when you still need to use template classes! It is not duplicate of linked question! – Illia Moroz Dec 15 '19 at 15:30
  • 2
    I see, reopened. But the question needs a [mcve] instead of a code description. – HolyBlackCat Dec 15 '19 at 15:33
  • I'm tempted to say yes, that is the right way to do it, but I would need a concrete example to be sure. –  Dec 15 '19 at 15:42
  • Thanks for the answers, Just updated the question to include reproducible example. – Illia Moroz Dec 15 '19 at 17:00

1 Answers1

2

Since template definitions can't break One Definition Rule, if duplicated, they should be accurate duplicates.

[C++14: 3.2/6]: There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.5) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements [..]

Edited question:

Each translation unit goes through separate translation and does not share preprocessor definitions with the others. That's why you end up with multiple definitions in your code. What you need here is a forward declaration. See this answer for details.

tejasvi88
  • 635
  • 7
  • 15