How to declare/define interdependent templates in C++?

前端 未结 2 654
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-20 05:02

Usually in C++ when I need interdependencies between classes, I use forward declarations in the header files and then include both header files in each cpp file.

How

相关标签:
2条回答
  • 2020-12-20 05:16

    You can utilize fine-grained headers:

    //  A.forward.hpp
    template<typename T> struct A;
    
    //  A.decl.hpp
    #include "A.forward.hpp"
    #include "B.forward.hpp"
    
    template<typename T> struct A
    {
        void RunA(B<T> *pB);
    };
    
    //  A.impl.hpp
    #include "A.decl.hpp"
    #include "B.hpp"
    
    template<typename T> void A< T >::
    RunA(B<T> *pB)
    {
        // need to do something to B here
    }
    
    //  A.hpp // this one should be included by code using A
    #include "A.decl.hpp"
    #include "A.impl.hpp"
    
    //  B.forward.hpp
    template<typename T> struct B;
    
    //  B.decl.hpp
    #include "B.forward.hpp"
    #include "A.forward.hpp"
    
    template<typename T> struct B
    {
        void RunB(A<T> *pA);
    };
    
    //  B.impl.hpp
    #include "B.decl.hpp"
    #include "A.hpp"
    
    template<typename T> void B< T >::
    RunB(A<T> *pA)
    {
        // need to do something to A here
    }
    
    //  B.hpp // this one should be included by code using B
    #include "B.decl.hpp"
    #include "B.impl.hpp"
    

    Obviously all of these headers also need some sort of header guards that I omitted here. Important notice: .impl.hpp headers are considered internal and should never be used by the outside code while .forward.hpp, .decl.hpp and .hpp can be used anywhere.

    This approach does introduce circular include dependencies, however this does not lead to problems: code structure produced by inclusion of headers ensures that code parts are included in the following order: forward declarations, class definitions, methods definitions.

    0 讨论(0)
  • 2020-12-20 05:29

    You can separate the declarations and definitions of classes. Therefore you can separate the declarations and definitions of template classes...

    You can separate the declarations and definitions of class methods. Therefore you can separate the declarations and definitions of template class methods:

    template<typename T> struct B;     // declaration
    
    template<typename T> struct A {     // definition
      void RunA(B<T> *pB);  // declaration
    };
    
    template<typename T> struct B {     // definition
      void RunB(A<T> *pA);   // declaration
    };
    
    // definition
    template<typename T>
    void A<T>::RunA(B<T> *pB) {
        // need to do something to B here
      }
    
    // definition    
    template<typename T>
    void B<T>::RunB(A<T> *pA) {
        // need to do something to A here
      }
    
    0 讨论(0)
提交回复
热议问题