轻松实施模板

时间:2010-12-09 20:26:13

标签: c++

假设我在collector.h中的某处编写了类模板声明:

template <class T, int maxElements>
class collector {

    T elements[maxElements];
    int activeCount;

public:

    collector();
    void process();
    void draw();

};

并在collector.cpp中实施其三种方法:

template <class T, int maxElements> 
collector<T, maxElements>::collector(){
    //code here
}

template <class T, int maxElements>
void collector<T, maxElements>::process(){
    //code here
}

template <class T, int maxElements>
void collector<T, maxElements>::draw(){
    //code here
}

有没有办法不写template <class T, int maxElements><T, maxElements> 对于每个功能的实现?这样的事情:

template <class T, int maxElements>{

    collector<T, maxElements>::collector(){
        //code here
    }

    void collector<T, maxElements>::process(){
        //code here
    }

    void collector<T, maxElements>::draw(){
        //code here
    }

}

6 个答案:

答案 0 :(得分:5)

将代码放在头文件中的类定义中。

[一旦尝试构建使用此类模板的代码,您最终可能会这样做。有关背景信息,请参阅here。来自@Pavel Minaev的被忽视的答案。]

答案 1 :(得分:1)

不,你每次都要写模板标题。

答案 2 :(得分:1)

通常,人们直接内联实现模板类。他们必须暴露出他们的全部资源(除非你明确地实例化这个地段),所以除此之外没有什么意义。

答案 3 :(得分:1)

  

有没有办法不编写模板和每个函数的实现?

不,没有在类模板的定义中内联定义模板成员,就没有办法做到这一点。

答案 4 :(得分:1)

以上许多人已经回答了你的问题的直接答案。

要了解有关最佳做法的更多信息,请参阅C++ Templates - The complete guide book的第6章。它讨论了哪个是声明和/或定义模板类,函数,成员函数的最佳位置:在.h / hpp或.cpp文件中。

答案 5 :(得分:1)

  1. 总有副本&amp;粘贴!

  2. 除非你有一个与你的编译器紧密耦合的智能C ++模板感知链接器,否则你必须在任何情况下将代码嵌入到标题中,问题就会消失。如果代码需要可移植,你可以在任何情况下都这样做。

  3. 如果你真的必须那么有一些有点不正面的预处理器宏解决方案:

    #define COLLECTOR_TEMPLATE template <class T, int maxElements>

  4. 显式实例化.cpp文件中您希望需要的所有类型,以便编译器可以生成代码先验,链接器将引用templkates与预先实例化的定义匹配(参见http://www.parashift.com/c++-faq-lite/templates.html#faq-35.13。但是,您将无法为新类型实例化模板。

  5. 对于单独编译模板以适用于任意实例化的类,编译器必须将模板源嵌入到目标文件中,然后当链接器需要特定的实例化来解析引用时,它必须提取该源并传递它返回编译器以生成实例化的目标代码,然后将其传递回链接器。这需要编译器和链接器一起工作,并且需要支持模板源嵌入的目标文件格式。

    大多数工具链都不支持,因此您必须在标头中使用内联定义,将模板限制用于定义它的同一源文件,或者#include包含定义的.cpp ;所有这三个实际上都是相同的 - 在单个编译单元中使编译器可以看到完整的模板定义,但第一个是最常规和最灵活的解决方案。