我想将cerr和cout包装在一个对象中,该对象有意丢弃发行版本中的所有内容。目的是确保开发人员可能忘记删除的某些调试输出不会显示给用户。
class Wrapper {
public:
Wrapper( std::ostream& os ):mOs(os){}
template <typename T>
DebugOnlyOsWrapper&
operator<<( T&& in ){
#ifndef NDEBUG
mOs << std::forward<T>(in);
#endif
return *this;
}
private:
std::ostream& mOs;
};
extern DebugOnlyOsWrapper dcout;
extern DebugOnlyOsWrapper dcerr;
但是,按如下所示调用运算符时出现“无法推断出模板参数'T'”错误:
dcerr << std::endl;
我在做什么错?无法从函数指针推断类型吗?
请注意,添加以下运算符可解决此问题,但是我想限制代码重复并了解问题的性质。
using CharT = std::ostream::char_type;
using Traits = std::ostream::traits_type;
Wrapper& operator<<(std::ios_base& (*func)(std::ios_base&) ){
#ifndef NDEBUG
mOs << func;
#endif
return *this;
}
Wrapper& operator<<(
std::basic_ios<CharT,Traits>&
(*func)(std::basic_ios<CharT,Traits>&)
){
#ifndef NDEBUG
mOs << func;
#endif
return *this;
}
Wrapper& operator<<(
std::basic_ostream<CharT,Traits>&
(*func)(std::basic_ostream<CharT,Traits>&)
){
#ifndef NDEBUG
mOs << func;
#endif
return *this;
}
谢谢
答案 0 :(得分:0)
问题在于std::endl
不是函数而是模板。
如果存在以下重载,则在此重载的调用中推导std :: endl的模板,因此它可以工作。
Wrapper& operator<<(
std::basic_ostream<CharT,Traits>&
(*func)(std::basic_ostream<CharT,Traits>&)
);
另一方面,通用模板没有足够的信息来解析std::endl
的模板参数。
因此,最后,我决定使用类似以下的内容:
class Wrapper {
public:
Wrapper( std::ostream& os ):mOs(os){}
using CharT = std::ostream::char_type;
using Traits = std::ostream::traits_type;
template <typename T>
Wrapper&
operator<<( T&& in ){
return impl(std::forward<T>(in));
}
DebugOnlyOsWrapper& operator<<(
std::basic_ostream<CharT,Traits>&
(*func)(std::basic_ostream<CharT,Traits>&)
){
return impl(func);
}
private:
template <typename T>
DebugOnlyOsWrapper& impl( T&& in ){
#ifndef NDEBUG
mOs << std::forward<T>(in);
#endif
return *this;
}
std::ostream& mOs;
};