单独的 .cpp 文件中的模板类专业化

Posted

技术标签:

【中文标题】单独的 .cpp 文件中的模板类专业化【英文标题】:Template class specialization in seperate .cpp file 【发布时间】:2022-01-03 03:11:43 【问题描述】:

我在foo.h 中有以下模板类特化:

using VisionMethod = enum

    TemplateMatching,
    ...
;

template <VisionMethod>
class Foo

    Foo() = delete;
;

template <>
class Foo<TemplateMatching>

public:
    static void get_pose();
;

并希望在foo.cpp 中实现它:

#include "foo.h"

void
Foo<TemplateMatching>::get_pose()

    std::cout << "Using foo<TemplateMatching>::get_pose()...\n";

但是当我尝试调用 foo&lt;TemplateMatching&gt;::get_pose() 例如main.cpp 仅包括 foo.h 之后。我可以实现我想要的,而不必在foo.hmain.cpp 中包含foo.cpp - 也许使用显式实例化?还是像foo.txx 我唯一的“干净”解决方案?

【问题讨论】:

不,你不能。如果 get_pose() 不包含在您正在编译和链接在一起的任何翻译单元中,编译器如何知道它的实现? 我想我可以做一些类似于显式实例化的事情,但我猜这行不通。 @Androvich 你所描述的应该可以通过wandbox.org/permlink/LDpxhgeYPkakWFwE 【参考方案1】:

您提出的建议已经有效(在添加#include &lt;iostream&gt; 之后),您可能忘记告诉编译器包含foo.cpp

点赞g++ main.cpp foo.cpp

https://wandbox.org/permlink/LDpxhgeYPkakWFwE

【讨论】:

嗯,我正在使用 CMake 并将 foo.cpp 作为源添加到库中,然后将 main 与库链接。 @Androvich 那么你的 CMake 配置可能有问题。我建议使用minimal reproducible example 发布一个新问题,并说明您正在寻求有关 cmake 的帮助。 好的,我会尝试这样做的。这只是一个庞大的项目,因此重新创建有点困难。【参考方案2】:

您需要在foo.h 中定义您的专用函数(即您在foo.cpp 中输入的内容)才能在main.cpp 中使用它

据我所知,这条规则是逃不掉的。但是,如果您想将标头和实现分开以使您的项目更清晰,一个非常常见的解决方案是将实现放在一个单独的文件中(我通常给它提供扩展名 .inl)并将其包含在末尾头文件。 这样,从人类的角度来看,它看起来像是头文件/实现程序的分离,但编译器仍然可以在其头文件中包含所有内容。此文件不是编译目标,因此您不必为其指定 .cpp 扩展名。

【讨论】:

我正在尝试找到一种方法,尽管使用模板,我仍可以将实现与标头分开。

以上是关于单独的 .cpp 文件中的模板类专业化的主要内容,如果未能解决你的问题,请参考以下文章

模板类源文件

当我将模板类与非模板类放在同一个 cpp 文件中时出现链接错误 - C++

VS 2011 模板类

如何在 cpp 文件中为多种类型创建模板类成员实现

仅具有静态方法的模板类使用 .cpp 文件实现给出错误

类模板作为模板特化中的参数a