Запись в два выходных потока с использованием специализации шаблона - PullRequest
0 голосов
/ 14 июля 2020

Я пытаюсь создать библиотеку журналирования, в которой пользователь мог бы выбрать запись в выходной файл или в файл, или в оба. Я хочу создать один класс, который обрабатывает запись (а позже и другие вещи, связанные с потоком).

Очевидной реализацией было бы использование оператора if для всех функций, но я хотел оптимизировать это, используя специализацию шаблонов . Я создал класс под названием DoubleStreamWriter:

template <typename _FST, typename _OST>
class DoubleStreamWriter {
public:
    DoubleStreamWriter(_FST fst, _OST ost) {
        fst_ = fst;
        ost_ = ost;
    }
    template <typename WT>
    void Write(WT obj) {
        (*fst_) << obj;
        (*ost_) << obj;
    }
    void Flush() {
        fst_->flush();
        ost_->flush();
    }

private:
    _FST fst_;
    _OST ost_;
};

template <>
class DoubleStreamWriter <std::nullptr_t, std::ostream*> {
public:
    DoubleStreamWriter(std::nullptr_t fst, std::ostream* ost) {
        (void)fst;
        ost_ = ost;
    }
    template <typename WT>
    void Write(WT obj) {
        (*ost_) << obj;
    }
    void Flush() {
        ost_->flush();
    }

private:
    std::ostream* ost_;
};

template <>
class DoubleStreamWriter <std::ofstream*, std::nullptr_t> {
public:
    DoubleStreamWriter(std::ofstream* fst, std::nullptr_t ost) {
        (void)ost;
        fst_ = fst;
    }
    template <typename WT>
    void Write(WT obj) {
        (*fst_) << obj;
    }
    void Flush() {
        fst_->flush();  
    }

private:
    static std::ofstream* fst_;
};

template <>
class DoubleStreamWriter <std::nullptr_t, std::nullptr_t> {
public:
    DoubleStreamWriter(std::nullptr_t fst, std::nullptr_t ost) {
        (void)fst;
        (void)ost;
        std::cout << ">>> cannot log anything with those settings" << std::endl;
    }
    template <typename WT>
    void Write(WT obj) {
        (void)obj;
    }
    void Flush() {

    }
};

Класс регистратора - это синглтон, который имеет частный указатель (dwriter_) этого типа. Однако я, очевидно, не могу изменить тип шаблонов во время инициализации, например, не могу преобразовать DoubleStreamWriter<ofstream*, ostream*> в DoubleStreamWriter <std::nullptr_t, ostream*>. Я попытался «исправить» это, используя вместо этого void*, но это просто отложило проблему до времени выполнения и было очень некрасиво.

Моя ошибка заключалась в том, что я думал, что decltype(stream_ptr) возвращает std::nullptr_t if stream_ptr установлено nullptr.

Как лучше всего это сделать? в качестве альтернативы, есть ли способ получить тот же тип, что и decltype(nullptr), при вызове decltype для указателя, установленного на nullptr?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...