Как поместить функции-члены шаблона класса c ++ в файл cpp, если они не используют аргументы шаблона? - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь реализовать шаблонный читатель класса в 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);
}

1 Ответ

0 голосов
/ 08 января 2019

Комментарий от wally уже имеет ответ. Просто переместите все, что не зависит от параметра шаблона, в базовый класс. Если вам нужно специализировать шаблон, это хорошая идея.

В шапке:

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) { /*...*/ }
...