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

4
我有一个名为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个回答

2

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

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中都有目标代码吗? - Benj
我假设您将此放入.cpp文件中,并使头文件不包含定义。然后,代码应该只在一个翻译单元中生成。缺点是您不能将该类用于任何未实例化的类型,因为编译器甚至不知道定义。(但请注意我的内联注释。这个几乎直接的函数转发请求进行内联处理。) - Kerrek SB
啊,我明白你的意思了,我现在会尝试一下。是的,我理解你关于内联的观点。我的原始方法实际上也将函数内联了。 - Benj
1
同时,尽可能添加const - 这将允许编译器进行更多的优化,并且实际上对于正确性可能是必要的。你的isDirectory方法肯定应该是const的。 - Kerrek SB
无论是否进行优化,我建议将inline bool isDirectory() const;放在声明中,否则一个const w32file<char> tempFile = ...;就无法访问isDirectory()了,是吧? - Tim Meyer
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接