c ++重载运算符<<对于std :: string

时间:2011-12-19 09:44:29

标签: c++ string operator-overloading

我刚刚看到另一个使用sprintf的天真C ++代码将C内置函数附加到一个字符数组中,我认为已经足够了。

我可以为std::string提供简单,轻量,附加和非格式化的功能,但是因为它会被检入团队的公共代码,所以我希望它是完美的,所以我需要一些建议在此功能的界面(即不在实际实现上)。

以下是可能的(我没有测试它,它只是预感):

  1. 重载“+=”运算符(可能在除std或global之外的其他名称空间中)
  2. 重载“<<”运算符(再次,在另一个名称空间中)
  3. 提供非操作员非成员函数(我猜,再次在另一个名称空间中)
  4. 另一个我没看到的简单解决方案?
  5. 每种解决方案的优点和缺点是什么(我偏好“+=”,甚至“<<”?

    注释

    • 重点不在于格式化。如果有人想要格式化,那么C ++流就可以了。我只想要简单,轻量级的一个语句/函数调用追加。
    • 使用另一个命名空间是因为我们没有被授权将代码添加到std命名空间,我不想污染全局命名空间,所以,是的,我想用户必须添加{{ 1}}用于using namespace SomeNamespace ;的{​​{3}}命名空间
    • 我正在使用<utility> rel_ops。我想扩展它以处理其他简单类型。
    • 在代码方面使用字符串流权重过多(声明流,附加,然后检索std::string以将其放入字符串等等),以及我想要的最后一件事是在每次调用时实现字符串流的语法加糖内联函数。正如您在下面的示例中所看到的,stringstream解决方案太冗长

    .str()

4 个答案:

答案 0 :(得分:3)

我会使用ostringstreamstream manipulators来替换sprintf。这不值得reinventing the wheel

答案 1 :(得分:3)

  1. boost::format怎么样?然后你可以写:

    std::string first("world");
    std::string s = (boost::format("hello %1%") % first).str();
    
  2. 或者创建一个包装类,您可以这样使用:

    int i(2);
    std::string s = (Format() + "Hello " + first + " " + i).str();
    

    Format()之类的东西(没有提升):

    class Format
    {
        public:
            template <typename T>
            Format &operator+(const T& v) {
                m_sstr << v; 
                return *this;
            };
            const std::string &str() const { return m_sstr.str(); };
        private:
            std::stringstream m_sstr;
    };
    

答案 2 :(得分:3)

C ++ 11附带了一组重载的std :: to_string函数。

示例原型:

std::string to_string( int value );

允许用户覆盖它们(在C ++ 11中)。您现在需要自己的命名空间。

您可以针对您选择的类型实施自己的设置。它可以用于面向未来的代码。

您可以将代码用作:

std::string s;
s+=std::to_string(1);

答案 3 :(得分:0)

boost :: lexical_cast为您提供了一个潜在的模型 - 编写一个可以处理您需要的任何数据类型的函数,将它们转换为适合您的目的的字符串(并且您可以像您一样优化它)需要/能够),并返回它们以与operator +(string,string)一起使用。

根据您的偏好,使用普通重载或模板特化来专门化每种类型的函数。 lexical_cast使用模板,因此它可以通过任何正在定义的流操作符来处理任何事情,但是你的用例远比这个更窄,所以你绝对可以从中获得更多的性能。