Splitting templated C++ classes into .hpp/.cpp files--is it possible?

前端 未结 16 834
被撕碎了的回忆
被撕碎了的回忆 2020-11-22 17:27

I am getting errors trying to compile a C++ template class which is split between a .hpp and .cpp file:

$ g++ -c -o main.o main.cpp         


        
16条回答
  •  有刺的猬
    2020-11-22 17:52

    The place where you might want to do this is when you create a library and header combination, and hide the implementation to the user. Therefore, the suggested approach is to use explicit instantiation, because you know what your software is expected to deliver, and you can hide the implementations.

    Some useful information is here: https://docs.microsoft.com/en-us/cpp/cpp/explicit-instantiation?view=vs-2019

    For your same example: Stack.hpp

    template 
    class Stack {
    
    public:
        Stack();
        ~Stack();
        void Push(T val);
        T Pop();
    private:
        T val;
    };
    
    
    template class Stack;
    

    stack.cpp

    #include 
    #include "Stack.hpp"
    using namespace std;
    
    template
    void Stack::Push(T val) {
        cout << "Pushing Value " << endl;
        this->val = val;
    }
    
    template
    T Stack::Pop() {
        cout << "Popping Value " << endl;
        return this->val;
    }
    
    template  Stack::Stack() {
        cout << "Construct Stack " << this << endl;
    }
    
    template  Stack::~Stack() {
        cout << "Destruct Stack " << this << endl;
    }
    

    main.cpp

    #include 
    using namespace std;
    
    #include "Stack.hpp"
    
    int main() {
        Stack s;
        s.Push(10);
        cout << s.Pop() << endl;
        return 0;
    }
    

    Output:

    > Construct Stack 000000AAC012F8B4
    > Pushing Value
    > Popping Value
    > 10
    > Destruct Stack 000000AAC012F8B4
    

    I however don't entirely like this approach, because this allows the application to shoot itself in the foot, by passing incorrect datatypes to the templated class. For instance, in the main function, you can pass other types that can be implicitly converted to int like s.Push(1.2); and that is just bad in my opinion.

提交回复
热议问题