我正在尝试在g ++ --std = c ++ 17中实现一个模板化的读取器类,该类不会针对正在读取的任何流类型提取所有各种系统标头。
我可以使用pimpl模式将模板参数与基本实现分开,但是我感觉应该可以通过指定以某种方式指定该函数的编译单元定义不会随模板参数改变而避免这种情况。
我也可以使用显式专业化,但是定义每个专业化都过于繁琐。
在标题中:
template<typename Parser>
class FileStream
{
Parser& parser;
int fd;
FileStream::FileStream(const char* filename, Parser& parser)
: parser(parser)
{
init(filename);
}
void init(const char* filename); // Preferably, implementation would go into .cpp file since this function does not use any template parameters
void step(char* buf, size_t len)
{
// This function needs to be in the header because it uses parser
parser.processMessage(buf, len);
}
};
在.cpp文件中:
// Let's try to not include these headers in the template definition header
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
template< /* ??? */ >
void FileStream::init(const char* filename)
{
// Note: No template parameters are used in this function
fd = open(filename, O_RDONLY);
}
答案 0 :(得分:1)
沃利的评论已经有了答案。只需将不依赖于模板参数的所有内容移动到基类中即可。一旦您必须专门化模板,无论如何这是一个好主意。
在标题中:
struct foo_base {
void init(const char* filename);
};
template <typename T>
struct foo : foo_base { /*...*/ };
// ... implement methods that depend on the template parameter
在源中:
#include <foo.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void foo_base::init(const char* filename) { /*...*/ }