简洁灵活的组成字符串的方式

Concise way of flexibly composing a string?

本文关键字:字符串 方式 简洁      更新时间:2023-10-16

灵活组合字符串的简洁方式是什么?我不喜欢使用宏。

例如,我可能想将int转换为十六进制格式的字符串,填充为10个字符的宽度,连接到字符串,另一个数字,…

基本上,我想要ostringstream/printf的灵活性,但是在一行代码上。

我以前用过这样的东西:

#include <sstream>
class make_string
{
public:
    make_string() { }
    template <typename T>
    explicit make_string(T && rhs)
    {
        oss << rhs;
    }
    template <typename T>
    make_string &operator<<(T && rhs)
    {
        oss << rhs;
        return *this;
    }
    operator std::string() const
    {
        return oss.str();
    }
    std::string str() const
    {
        return oss.str();
    }
private:
    std::ostringstream oss;
};

用法如下:

string s = make_string() << "Hello, world" << '!' << 42 << 1.0;

或者像这样:

string s = make_string(4.0);

如果你想的话,它给了你在一个表达式中流式传输多个对象的灵活性,或者如果你需要的话,可以立即转换单一类型。它将隐式地转换为std::string,因此您可以直接将其赋值为1。它所需要的只是类型Tstd::ostream对象有一个流插入操作符。

或者(正如上面的评论者所建议的),如果您已经在项目中使用Boost,那么boost::lexical_cast()是另一个潜在的选择。你应该看看它的界面,然后选择一个你最喜欢的。

您可以使用这个实用函数:

// util.h
#include <string>
#include <sstream>
inline std::string to_str(basic_ostream<char>& str) {
    return dynamic_cast<std::ostringstream&>(str).str();
}

像这样使用:

// Example.cpp
#include <stdexcept>
#include "util.h"
using namespace std;
void f(int address) {
  runtime_error(to_str(ostringstream() << "Did not find instruction at: " << hex << address)));
}

另一种方法:

template <typename T>
std::string to_str(T&& t)
{
   std::ostringstream out;
   out << t;
   return out.str();
}