暂时覆盖输出流行为

时间:2016-02-28 12:20:58

标签: c++ iostream pretty-print ostream idiomatic

假设我有一个chars(或只是一个迭代器对)的向量,我想打印到ostream。现在,我不只是想要它打印 - 我希望它具有特定种类的间距,我想要一个不同的char值表示,而不是将它们脱口而出到终端(比如,如果它是可打印的并且是转义的2,则为char -digit或hex代码。

现在我不想在最低限度之外编写我自己的自定义代码 - 即只需要一点胶水和

void foo(ostream& os, char c) {
    os << c << ' ' << as_hex(c);
}

(这类似于运算符的自定义重载&lt;&lt;没有返回。)

我不想循环遍历vecotr,并且为每个角色手动调用abve我希望它表现得好像我只是将我的向量传输到我的outoput流,之后暂时改变了后者的属性。但偶尔我希望流回归正常,即使是相同的向量。

这可以合理地/惯用地完成吗?

3 个答案:

答案 0 :(得分:1)

我假设你知道运算符重载,你的主要问题是如何告诉运营商使用哪种格式化选项,即如何在流中存储任意信息。

std::ios_base(所有标准流类)派生的任何内容都有.iword()方法,该方法从某个内部存储返回long的引用,.pword()返回std::ios_base::xalloc()的引用1}}。可以通过调用{{3}}

获取这些呼叫的唯一索引

使用流存储来更改输出操作行为的示例:

void*
  

FOO
  {f,o,o}
  FOO

答案 1 :(得分:1)

因为重载是暂时的,我认为做一些像iomanip这样的东西会很好。这将允许做像

这样的事情
int main() 
{ 
    std::vector<char> v{'a', 'b'}; 
    /* v should be printed using foo_vector_print, perhaps
    *    next invocation should use a different format. */
    std::cout << foo_vector_print() << v << std::endl; 
}   

这个想法是有一些形式:

 stream << manip << vector;

,其中

  • stream << manip将返回存储对流的引用的类的对象。
  • ... << vector将使用特定格式打印,然后返回对原始流的引用。

以下程序显示了如何执行此操作:

#include <iostream>
#include <vector>


namespace detail
{

// A dummy class in detail namespace, simply records the original ostream object.
struct foo_vector_printer_imp
{
    std::ostream *m_os;
};

};


// This particular implementation simply prints out the vectors size.
std::ostream &operator<<(detail::foo_vector_printer_imp imp, const std::vector<char> &v)
{
    *imp.m_os << v.size();

    return *imp.m_os;
}


struct foo_vector_print{};


/* The result of piping a foo_vector_print into an ostream, 
*    is a foo_vector_printer_imp object recording the ostream */
detail::foo_vector_printer_imp operator<<(std::ostream &os, const foo_vector_print &)
{
    detail::foo_vector_printer_imp imp;
    imp.m_os = &os;
    return imp;
}


int main() 
{ 
    std::vector<char> v{'a', 'b'}; 
    std::cout << foo_vector_print() << v << std::endl; 
}   

答案 2 :(得分:0)

好吧,你必须在某处编写自定义代码 。您的矢量内容不会自行写入std::ostream

从内容来看,您真的要问如何使用<<运算符来操作std::vector<char>。以下示例可以帮助您入门:

#include <iostream>
#include <vector>

std::ostream &operator<<(std::ostream &o, const std::vector<char> &v)
{
    // Fill in the blanks here.
    return o;
}

// Example:

int main()
{
    std::vector<char> v;

    std::cout << v;

    return 0;
}