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

Posted

技术标签:

【中文标题】如何在 cpp 文件中为多种类型创建模板类成员实现【英文标题】:How can I create template class member implementations in the cpp file for multiple types 【发布时间】:2011-07-11 10:02:32 【问题描述】:

我有一个名为 w32file 的模板类,它可以与 wchar_t 和 char 一起使用。已声明:

template <typename T>
    class w32file  ... 

它有很多成员方法,比如这个:

inline bool isDirectory();

现在我知道我可以将这些成员方法的所有实现放在头文件中,然后它们会被编译到使用我的模板的任何目标文件中。但是,我真的不想要这个,因为这个类会被到处使用,并且会导致大量重复的目标代码。

所以目前,我有一个 cpp 文件,它链接到一个静态库,它执行以下操作:

bool w32utils::w32file<wchar_t>::isDirectory()

    auto dwAttr = GetFileAttributes(m_name.c_str());
    return ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);


bool w32utils::w32file<char>::isDirectory()

    auto dwAttr = GetFileAttributes(m_name.c_str());
    return ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);

现在,我的目标代码只创建了一次,但我必须在我的源代码中创建本质上相同的方法的两个副本。有谁知道解决这个问题的方法?有没有办法以模板化的方式将这两种实现扩展到我的目标文件中?

【问题讨论】:

【参考方案1】:

定义函数模板化并使用显式模板实例化:

namespace w32utils

  template <typename T>
  bool w32file<T>::isDirectory()
  
    const auto dwAttr = GetFileAttributes(m_name.c_str());
    return ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
  


  template class w32file<char>;
  template class w32file<wchar_t>;

请注意,我强烈建议将其放在标题中并内联

【讨论】:

嗯,这会以某种方式避免目标代码被多次创建吗?您会看到,使用我烦人的复制/粘贴方法,我至少可以将目标代码放在一个 dll 中。这不会导致目标代码出现在每个碰巧使用 w32file 的 dll 中吗? 我假设您将其放入 .cpp 文件中并保持标头没有定义。然后代码应该只在那个翻译单元中生成。缺点是你不能将类用于你没有实例化的任何类型,因为编译器甚至不知道定义。 (但请注意我关于内联的评论。这个几乎直接的函数转发请求被内联。) 啊,我明白你的意思了,我现在就试试这个。是的,我同意你关于内联的观点。我原来的方法实际上也内联了函数。 还要尽可能添加const - 这将允许编译器进行更多优化,并且它实际上可能是正确性所必需的。你的isDirectory 方法肯定是const @Itjax:(对不起,我的意思是const auto,而不是const auto &amp;,这已经被破坏了。)不过,我指的不是函数参数,而是本地的dwAttr。通过将其设为 const,编译器知道它可以尝试完全删除该变量。当然,它也可以从非常量变量中计算出这一点,但是如果您真正拥有的范围内的常量,那为什么不精确呢?

以上是关于如何在 cpp 文件中为多种类型创建模板类成员实现的主要内容,如果未能解决你的问题,请参考以下文章

c++创建链表为啥要用类模板

-cpp代码重用(其他继承&模板)

CPP复习笔记 2

在 .cpp 文件中使用类的静态成员

如何将模板类添加为普通类中的成员

使用模板重载类的成员函数