我会直截了当地说:我有一个类模板,其中包含一个引用并更新信息:
template<class T>
class Parser {
T& m_ref;
public:
typedef T ValueType;
Parser(T& ref): m_ref(ref) {}
virtual void read(std::istream&);
};
现在,我有另一个模板创建一个新对象并使用此接口更新它,为此我有一个保存解析器的字段。
但是,我想将updater用于派生自T的类,由于Parser<Derived>
不从Parser<Base>
继承,因此这是不可能的。
我创建了这个解决方法,使用了一个继承自Parser<Base>
但更新为Parser<Derived>
的中间类:
template<class T>
struct dummy {};
template<class T>
class Creator {
typedef shared_ptr<Parser<T> > ParserPtr;
typedef shared_ptr<T> ValuePtr;
ValuePtr m_output;
ParserPtr m_parser;
template<class ParserType>
class LocalParser : public Parser<T> {
ParserType m_parser;
public:
LocalParser(typename ParserType::ValueType& val):
Parser<T>(/*???*/), //problems start here, I must initialize the base
m_parser(val) {}
void read(std::istream& is) { //use polymorphism to update into some derieved reference
m_parser.read(is);
}
};
public:
Creator(): //Uses Parser<T> as default parser
m_output(new T),
m_parser(new Parser<T>(*m_output)) {}
template<class ParserType>
Creator(dummy<ParserType>) { //Use any parser
auto temp = make_shared(new typename ParserType::ValueType);
m_output = temp;
m_parser = maked_shared(new LocalParser<ParserType>(*temp));
}
virtual ValuePtr read()(std::istream& is) {
m_parser->read(is);
return m_output;
}
};
基本上LocalParser
是一个继承自Parser<T>
的中间类,但会更新来自其基础的不同引用。
这里的问题是如何初始化Parser<T>
,特别是当T
是抽象的时候(这是99%的时间我实际上使用派生解析器的这个类)。
我的问题归结为&#34;如何定义对(可能)使用WON的抽象类的引用?&#34; (或者是否有任何其他类型的工作,我不会定义继承自Parser<T>
)的中间人。
编辑:Parser界面是我无法更改的单独代码。
答案 0 :(得分:3)
您无法创建空引用。引用必须引用某些内容。这是参考和指针之间的关键差异之一。事实上,为您提供了一个可能的解决方案:
T& ref; // error
T& ref = nullref; // no such thing
T* ptr = nullptr; // "empty" pointer!
允许使用boost::optional
的另一个可能更明确的解决方案是使用{{3}}:
boost::optional<T&> opt_ref; // empty optional
opt_ref = some_t;