Мне нужно определить объект конфигурации. я использую boost::property_tree
для импл, но я не хочу выставлять детали Импл в моем интерфейсе, или должен #include
повысить файлы в моем интерфейсе.
Проблема в том, что я хотел бы использовать шаблонный метод ptree для получения значений,
template <typename T>
T get(const std::string key)
Но это невозможно (?)
// Non compilable code (!)
// Interface
class Config {
public:
template <typename T>
T get(const std::string& key);
}
// Impl
#include "boost/property_tree.h"
class ConfigImpl : public Config {
public:
template <typename T>
T get(const std::string& key) {
return m_ptree.get(key);
}
private:
boost::ptree m_ptree;
}
Одним из вариантов является ограничение типов, которые я могу «получить», например:
// Interface
class Config {
public:
virtual int get(const std::string& key) = 0;
virtual const char* get(const std::string& key) = 0;
}
// Impl
#include "boost/property_tree.h"
class ConfigImpl : public Config {
public:
virtual int get(const std::string& key) { return m_ptree.get<int>(key) };
virtual const char* get(const std::string& key) { return m_ptree.get<const char*>(key); }
private:
boost::ptree m_ptree;
}
Но это довольно уродливо и не масштабируется.
Есть ли лучшие варианты там?
У вас не может быть шаблонов виртуальных функций, но вы могли бы использовать другой техника интерфейса, который называется Pimpl идиома.
Вы должны использовать шаблон и тип стирания, чтобы достичь этого, посмотрите это видео cppcon под названием: практическое стирание типов. (https://www.youtube.com/watch?v=5PZVuUzP34g)