C++模板问题
我正在尝试构建小型记录器库。 我是facig C++模板的一些问题。 这是我的课堂结构。C++模板问题
class abstract_logger_t {
public:
typedef abstract_logger_t logger_type;
template<typename data_t>
abstract_logger_t& log(const data_t& data) {
return *this;
}
};
class stdout_logger_t : public abstract_logger_t {
public:
typedef stdout_logger_t logger_type;
template<typename data_t>
stdout_logger_t& log(const data_t& data) {
cout << data << endl;
return *this;
}
};
template<typename logger_t, typename data_t>
void output(logger_t& logger, const data_t& data) {
static_cast<typename logger_t::logger_type&>(logger).log(data);
cout << data;
}
template<typename data_t>
abstract_logger_t& operator<< (abstract_logger_t& logger, const data_t& data) {
output(logger, data);
return logger;
}
stdout_logger_t logger;
logger << "Hi " << 1;
这里我期待stdout_logger_t :: log被输出调用。 但它看起来像派生类型正在丢失 和abstract_logger_t :: log最终被调用。 有人可以告诉我,如果我做错了什么?
template<typename data_t>
abstract_logger_t& operator<< (abstract_logger_t& logger, const data_t& data) {
output(logger, data);
return logger;
}
在这里,你传递什么logger
,编译器将其转换为abstract_logger_t&
。您还需要制作第一个参数模板。
template<typename T, typename data_t>
T& operator<< (T& logger, const data_t& data) {
output(logger, data);
return logger;
}
没有必要让事情比他们应该更复杂。 这里的遗产是无用的,除非你想使用虚拟方法,在这种情况下,你将不会使用模板。 这里是你的代码的更新版本。只需添加其他记录器类,当你需要新的记录器类。
class stdout_logger_t
{
public:
typedef stdout_logger_t logger_type;
template<typename data_t>
logger_type& log(const data_t& data) {
cout << data << endl;
return *this;
}
};
class lazy_logger_t
{
public:
typedef lazy_logger_t logger_type;
template<typename data_t>
logger_type& log(const data_t& data) {
return *this;
}
};
template<typename logger_t, typename data_t>
void output(logger_t& logger, const data_t& data) {
logger.log(data);
}
template<typename logger_t, typename data_t>
logger_t& operator<< (logger_t& logger, const data_t& data) {
output(logger, data);
return logger;
}
stdout_logger_t logger;
lazy_logger_t lazyLogger;
logger << "Hi " << 1;
lazyLogger << "Hi " << 1;
要小心,我非常确定这个记录系统不能用于std :: endl。
另外,这将在'_'链中的__every__表达式之后放置一个'std :: endl'。所以'logger sbi 2010-07-26 09:07:31
看来你是混淆模板与运行时多态性。另外,您的abstract_logger_t类不是抽象的。你使用logger_t = abstract_logger_t从运营商< <输出输出。模板参数是通过检查静态类型而不是动态类型来确定的。模板参数推导和模板实例化是编译时机制。这应该回答你的问题。
BTW:约定是使用CamlCase名称作为模板参数。
Err ..谁的约定?当然不是我的.... – 2010-07-24 14:31:40
你为什么施放你的记录器?如果没有静态演员,模板不会工作吗? – josefx 2010-07-24 13:02:31