Stati c полиморфизм с зависимым внутренним классом - PullRequest
0 голосов
/ 15 марта 2020

У меня есть следующий - упрощенный - код C ++ 11, используемый для отвлечения чтения из хранилища объектов или из файловой системы:

  • ObjectLikeReader::open - это виртуальная функция, возвращающая * Реализация 1005 *.
  • Handle::read читает что-то из базового объекта.
class Handle {
   public:
    virtual std::string read() = 0;
    virtual ~Handle() = default;
};

class ObjectLikeReader {
   public:
    virtual std::unique_ptr<Handle> open() = 0;
    virtual ~ObjectLikeReader() = default;
};

// Specialization

class FileReader : public ObjectLikeReader {
   public:
    std::unique_ptr<Handle> open() override;

   private:
    class InternalHandle;
};

class FileReader::InternalHandle : public Handle {
   public:
    InternalHandle(){};
    std::string read() override {
        return "hello";
    }
};

std::unique_ptr<Handle> FileReader::open() {
    return std::unique_ptr<Handle>(new InternalHandle());
}

std::string read(ObjectLikeReader* reader) {
    return reader->open()->read();
}

int main() {
    FileReader r;
    std::cout << read(&r) << std::endl;
}

Вся диспетчеризация выполняется с использованием виртуальных функций и работает отлично. Помимо производительности в узком l oop, которая командует, обращая внимание на полиморфизм stati c:

#include <iostream>
#include <string>

template <class T>
class Handle {
   public:
    std::string read() {
        return static_cast<T*>(this)->read();
    }

   protected:
    ~Handle() = default;
};

template <class T, class H>
class ObjectLikeReader {
   public:
    Handle<H> open() {
        return static_cast<T*>(this)->open();
    }

   protected:
    ~ObjectLikeReader() = default;
};

// Specialization

class FileReaderHandle : Handle<FileReaderHandle> {
   public:
    FileReaderHandle(){};
    std::string read() {
        return "hello";
    }
};

class FileReader : public ObjectLikeReader<FileReader, FileReaderHandle> {
   public:
    FileReaderHandle open() {
        return FileReaderHandle();
    }
};

int main() {
    FileReader r;
    std::cout << r.open().read() << std::endl;
}

Я не совсем удовлетворен этой реализацией. Есть ли способ достичь той же функциональности, что и во втором примере?:

  • Не требуя двойной шаблонный параметр (черты, может быть, не уверен ...),
  • В идеале, не имея сделать дескриптор класса publi c.

Спасибо!


Редактировать: Исправлено глупое определение отсутствующего конструктора, приводящее к ошибке компиляции.

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