链接模板类函数 [英] Linking template class functions

查看:157
本文介绍了链接模板类函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现自己对模板的理解有一个挑战,我理解模板的源代码必须放在头文件中,以便访问模板被实例化的所有依赖类型。

I've found a challenge on my own understanding of templates, I understand that the source code of a template must be placed into the header file in order to access to all the dependant types where the template is instanced.

所以,在这个例子中:

// This code cannot be placed in the cpp file
template <typename T> T foo(T v)
{
    return -v;
}

T foo / code>必须放在头文件中,然后,当 foo 函数被实例化到某处时,创建真实body函数,替换 T 符号与真实类型。使用此代码:

The body of T foo(T v) MUST be placed in the header file, then, when foo function is instanced somewhere, the "real" body function is created replacing the T symbol with the real type. With this code:

int bar = 5;
float baz = 6.66f;
bar = foo<int>(bar);
baz = foo<float>(baz);

模板实例化机制根据先前定义的模板创建以下函数:

The template instantiation mechanism creates the following functions based on the previously defined template:

int foo(int v)
{
    return -v;
}

float foo(float v)
{
    return -v;
}

但是,当我们有一个模板类时,不使用依赖类型:

But, when we have a template class, the class can have functions that doesn't use the dependant type at all:

template <typename T> class Foo
{
    Foo() : mistery(0), value(0) {}; // We're using the dependant type.
    AddMistery() { ++mistery; }; // We are not using the dependant type.

    int mistery;
    T value;
};

我第一次认为 AddMistery 放在cpp文件中,因为这个方法不使用依赖类型,但是当我尝试它,连接失败。在这一刻,我拍了我的脸,记住模板类的不同实例不是相同的类。所以,当链接器做它的工作,它寻找 AddMistery 方法的身体,并没有找到它,因为ir放置到cpp文件:

I first figured that the AddMistery method could be placed in the cpp file, because this method isn't using the dependant type, but when I tried it, failed while linking. At this moment I slapped my face remembering that the different instances of template classes are not the same class. So, when the Linker is doing it's job, it looks for the body of the AddMistery method and does not found it because ir is placed into the cpp file:

// Foo.h
template <typename T> class Foo
{
    Foo() : mistery(0), value(0) {}; // We're using the dependant type.
    AddMistery(); // We are not using the dependant type.

    int mistery;
    T value;
};

// Foo.cpp
#include "Foo.h"

template <typename T> Foo<T>::AddMistery()
{
    ++mistery;
}

// Main.cpp
#include "Foo.h"

int main(int argc, char **argv)
{
    Foo<int> i;
    Foo<float> f;

    i.AddMistery(); // Link Error, where's the Foo<int>::AddMistery body?
    f.AddMistery(); // Link Error, where's the Foo<float>::AddMistery body?

    return 0;
};

所以,最后,这里是一个问题:有一种方法来拆分模板类, cpp文件,将所有非类型依赖方法的主体移动到cpp,而不是将所有的方法体保存到头文件中。

So, finally, here is the question: There's a way to split a template class between the header and cpp file, moving the body of all non type-dependant methods to the cpp instead of keeping all the methods body into the header file?.

推荐答案

简单的答案是没有,因为类模板不是一个类,除非你使用某个模板参数来实例化它。所以没有 Foo :: AddMystery()来实现。

The short answer is no, because a class template is not a class unless you are instantiating it with a certain template parameter(s). So there is no Foo::AddMystery() to implement.

想想这样:知道依赖类型,因为它们有一个隐式的第一个参数,它是一个指向它们类的对象的指针。所以

Think of it this way: member function have knowledge of the dependent type, because they have an implicit first parameter, which is a pointer to an object of their class. So

Foo<int> f;
f.AddMistery();

相当于

Foo<int> f;
Foo<int>::AddMistery(&f);

如果您有某些类型的模板实例化,在 .cpp 文件中实现 Foo< int> :: AddMistery ,但这与该函数在其正文中不需要模板参数。

If you have instantiations of the template for certain types, then you could implement, say, Foo<int>::AddMistery in a .cpp file, but this has nothing to do with the function not requiring the template argument in its body.

这篇关于链接模板类函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆