c – 确保参数是控制台的输出流
我正在尝试制作一个颜色的流操纵器,用于输出到控制台.它工作,改变文本和背景的颜色:
std::cout << ConColor::Color::FgBlue << 123 << "abc"; //text is blue,sticky 问题在于签名: std::ostream &FgBlue(std::ostream &); 此签名允许派生类,例如std :: ostringstream,但是无法更改字符串流的颜色.无论是否使用这样的参数调用,该函数都会改变控制台的颜色. 因此,我想确保参数是std :: cout,std :: wcout等等.我希望在将来的标准中添加更多std :: ostream对象时,它是通用的. 我尝试了许多涉及std :: is_same和std :: is_base_of的事情,当前者不起作用时,只是为了最终意识到它没有意义,因为任何参数类型都继承自std :: basic_ostream<>当传递给函数时,将被转换为我正在比较的类型,给出误报. 这最终导致我在下面的回答(可变参数模板模板参数?哇,这是一个满口的!)然而,有几个问题: >编译器必须支持可变参数模板.我更希望解决方案适用于MSVC. 我鼓励人们发布任何其他解决方案,希望比我的更好,并且真的希望至少与VS11一起使用. 解决方法
这是检测std :: basic_ostream实例化的特性:
template<typename T> struct is_basic_ostream { template<typename U,typename V> static char (&impl(std::basic_ostream<U,V> *))[ std::is_same<T,std::basic_ostream<U,V>>::value ? 2 : 1]; static char impl(...); static constexpr bool value = sizeof(impl((T *)0)) == 2; }; 用于: template<typename T> void foo(T &) { static_assert(is_basic_ostream<T>::value,"Argument must be of type std::basic_ostream<T,U>."); } 我们使用模板参数推导来推断(非正确的)basic_ostream基类上的模板参数(如果有的话).作为一种更通用的解决方案,用单个可变参数替换U和V将允许在支持可变参数模板参数的编译器上编写通用的is_instantiation_of特性. 要检测stdout是否通过管道传输到文件(当然只能在运行时检测到),请使用isatty;见how to use isatty() on cout,or can I assume that cout == file descriptor 1? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |