繁体   English   中英

C ++模板和目标代码实例化

[英]C++ templates and object code instantiation

关于这个问题,我想更好地了解C ++模板系统如何处理这个问题

据我所知,基于模板的类和函数通常放置在头文件中。 这是由于管理通用数据类型的技术问题导致的,这些特征在原则上是未知的。 一旦知道它们,编译器便可以生成适合于所需数据类型的可执行代码。

在头文件something.h ,我们的类应定义如下:

template <typename T>
class Something
{
    public:
        void setElement (T &elem) {
            element = elem;
        }
        T getElement () {
            return element;
        }
    private:
        T element;
};

现在,让我们分割源代码定义和类定义:

以下类定义将写在something.h

template <typename T>
class Something
{
    public:
        void setElement (T &elem);
        T getElement ();
    private:
        T element;
};

虽然下面的方法将写在something.cpp

#include "something.h"

template <typename T>
void Something<T>::setElement (T &elem)
{
    element = elem;
}

template <typename T>
T Something<T>::getElement ()
{
    return element;
}

除非我们在something.cpp内声明一些特定类型的实例,否则如果将其编译为目标文件,我们将不会在其中获得任何文本部分:

dacav@mithril:<tmp>$ g++ something.cpp  -c
dacav@mithril:<tmp>$ objdump -D something.o 

something.o:     file format elf64-x86-64


Disassembly of section .comment:

0000000000000000 <.comment>:
   0:   00 47 43                add    %al,0x43(%rdi)
   3:   43 3a 20                rex.XB cmp    (%r8),%spl
...
...
  20:   34 2e                   xor    $0x2e,%al
  22:   31 00                   xor    %eax,(%rax)
dacav@mithril:<tmp>$

正如Martin York所示,我们可以强制编译器为某些特定的数据类型生成代码,以控制可以使用哪些类型以及不能使用哪些类型。 但是,如果我们不希望受到任何限制怎么办?

如果想实例化任意类型的模板,只需将实例化所需的所有内容都放在头文件中。 这意味着将功能主体(需要可用以实例化)放在头文件中,而不是.cpp文件中。

如果只想在单独的文件中进行声明和定义,以更好地构造源代码,则可以使用如下方案:

东西

// Just the declaration

template<typename T>
class Something {
  void foo();
};

// include the header file with the definitons
#include "something.impl.h"

东西

// Put definitions here

template<typename T>
void Something<T>::foo() {
}

简而言之,您已经塞满了。 该标准确实定义了“导出”关键字,该关键字应从文件中导出可实例化(即原始格式,而不是特定类型)的模板。 但是,现实情况是,几乎没有主要的编译器支持它,并且说他们永远不会支持它。 因此,它已从C ++ 0x中删除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM