我想将模板类的 .h 和 .cpp 分开。
这是我在做什么:

  • 我直接写了 .h 和 .cpp 就像没有模板一样。所以它创建了一个像 Link 2019 Template exception
  • 这样的异常
  • 有一些解决方案可以处理这个 How to define template class header and implement it in another cpp 。我选择解决方案 3。
  • 根据我在#endif inside header 之前添加的解决方案。(仍然*.cpp包括*.h) (下面的代码代表这一步) 它给出

  • 根据研究摆脱这个错误的方法是(循环依赖)从 *.cpp 中删除 #include *.h 但这次


  • 发生。我的问题是我是否将 *.cpp 包含到 *.h 文件中。我们如何按预期构建项目?或者这个解决方案已经过时了?
    // TestTemp.h
    #ifndef _TESTTEMP_H_
    #define _TESTTEMP_H_
    template<class T>
    class TestTemp
    {
    public:
        TestTemp();
        void SetValue(T obj_i);
        T Getalue();
    private:
        T m_Obj;
    };
    #include "TestTemp.cpp"
    
    #endif
    
    // TestTemp.cpp
    #include "TestTemp.h"
    template <class T>
    TestTemp<T>::TestTemp()
    {
    }
    template <class T>
    void TestTemp<T>::SetValue(T obj_i)
    {
    }
    
    template <class T>
    T TestTemp<T>::Getalue()
    {
        return m_Obj;
    }
    
    #include "TestTemp.h"
    
    int main()
    {
        TestTemp<int> a;
        a.Getalue();
        return 0;
    }
    

    最佳答案

    与普通类的成员函数不同,模板类的成员函数不能单独编译链接到可执行文件中。模板的成员在使用时必须对编译器可见。这就是那篇可怕的文章中包含的所有荒谬内容的意义所在。

    最简单的方法是将定义直接放入模板定义中:

    #ifndef TEST_H
    #define TEST_H
    
    template <class Ty>
    class test {
    public:
        void f() { /* whatever */ }
    };
    #endif
    

    这有一个缺点,即较大的类变得不可读(参见 Java)。所以下一步是将定义移到模板之外,但将它们保留在标题中:
    #ifndef TEST_H
    #define TEST_H
    
    template <class Ty>
    class test {
    public:
        void f();
    };
    
    template <class Ty>
    void test<Ty>::f() { /* whatever */ }
    
    #endif
    

    很多人觉得还是太乱了,想把定义放到一个单独的文件里。这也没关系,但是您必须确保在使用原始 header 时包含该单独的文件:
    #ifndef TEST_H
    #define TEST_H
    
    template <class Ty>
    class test {
    public:
        void f();
    };
    
    #include "test.imp"
    
    #endif
    

    这是文件“test.imp”:
    #ifndef TEST_IMP
    #define TEST_IMP
    
    template <class Ty>
    void test<Ty>::f() { /* whatever */ }
    
    #endif
    

    请注意,“test.imp”实际上是一个头文件,因此它通过 #include "test.imp" 中的 test.h 指令进入您的代码。它不能单独编译,所以应该用 .cpp 扩展名命名 而不是 ,这充其量会产生误导。

    关于C++ 模板头 cpp 分离,包括 *.cpp 到 *.h 的解决方案不再工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34043432/

    10-11 22:38
    查看更多