草庐IT

c++ - 如何在自定义对象的 << 运算符中添加自定义前缀

coder 2024-02-16 原文

有没有办法在 operator<< 中添加自定义前缀对于我实现的对象?

例如:

class A {
   public:
    std::string id;
    int count;
};

std::ostream &operator<<(std::ostream &os, const A &a)
{
    os << os.prefix() << "Id: " << a.id << "\n";
    os << os.prefix() << "Count: " << a.count << "\n";
    return os;
}

如果我这样做:

A a;
a.id = "foo";
a.count = 1;
std::cout << a << std::endl;

输出将是:

Id: foo
Count: 1

我想做这样的事情:

std::cout << set_prefix(" -") << a << std::endl;
std::cout << set_prefix("==>") << a << std::endl;

要得到这样的输出:

 -Id: foo
 -Count: 1
==>Id: foo
==>Count: 1

建议使用 std::setfillos.fill ,但是 std::setfill需要一个char作为参数,我需要一个自定义字符串。

解决方案

查看operator<<(std::basic_ostream)文档,我发现了这个:

Before insertion, first, all characters are widened using os.widen(), then padding is determined as follows: if the number of characters to insert is less than os.width(), then enough copies of os.fill() are added to the character sequence to make its length equal os.width(). If (out.flags()&std::ios_base::adjustfield) == std::ios_base::left, the fill characters are added at the end of the output sequence, otherwise they are added before the output sequence. After insertion, width(0) is called to cancel the effects of std::setw, if any.

所以对我有用的解决方案是在开始时保存流的原始宽度,而不是在必要时恢复它们。

std::ostream &operator<<(std::ostream &os, const A &a)
{
    auto w = os.width();
    os << std::setw(w) << "" << "Id: " << a.id << "\n";
    os << std::setw(w) << "" << "Count: " << a.count;
    return os;
}

然后:

std::cout << a << std::endl;
std::cout << std::setw(4) << a << std::endl;
std::cout << std::setfill('>') << std::setw(2) << a << std::endl;

给出以下输出:

Id: foo
Count: 1
    Id: foo
    Count: 1
>>Id: foo
>>Count: 1

最佳答案

也许有点矫枉过正,但你可以使用这样的东西:

#include <iostream>
#include <sstream>

struct line_buffered_stream {
    std::ostream& out;
    std::stringstream ss;
    std::string prefix;
    line_buffered_stream(std::ostream& out,std::string prefix) : 
        out(out),prefix(prefix) {}        
    template <typename T> 
    auto operator<<(const T& t) -> decltype(this->ss << t,*this) { 
        ss << t; 
        return *this;
    }        
    ~line_buffered_stream(){
        std::string line;
        while (std::getline(ss,line)){
            out << prefix << line << "\n";
        }
    }
};

int main() {
     line_buffered_stream(std::cout,"==>") << "a\nb\n";
     line_buffered_stream(std::cout,"-->") << "a\nb\n";        
}

输出:

==>a
==>b
-->a
-->b

Live Demo

请注意,上面的实现并不意味着用作临时的,其生命周期仅限于一行代码。如果您不喜欢这样,则必须添加一些机制来将流刷新到 std::cout,而不是等到析构函数被调用。

关于c++ - 如何在自定义对象的 << 运算符中添加自定义前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52561764/

有关c++ - 如何在自定义对象的 << 运算符中添加自定义前缀的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  3. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  4. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  5. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  6. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  7. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  8. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  9. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  10. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

随机推荐