有没有一种标准的方法将一个类转换为字符串?

24
在Java中,标准是定义一个方法toString() ,以返回类的字符串表示形式。除了重载operator<<之外,在C ++中是否有类似的标准?我知道有std::to_string()方法用于获取数字的字符串表示形式。 C++标准是否提到定义方法to_string()以类似的方式为类服务,或者是否有C++程序员遵循的常见做法?

似乎需要 toString() 方法的结构体数量会被不需要的数量所压倒。这只是我的个人观点。 - Fantastic Mr Fox
2
这个问题:“除了标准的方式,还有一个标准的方式吗?” - Lightness Races in Orbit
8
operator std::string() const; 挑战我 - Ryan Haining
1
感谢大家的评论和见解。我不是在寻找这样一个方法会做什么(即返回的字符串中会包含什么),而是更多地寻找一个“通用”的方法名称,得到大家的认可(因此成为标准)。如果一个类的编写者决定提供一个返回该类的字符串表示的方法,至少有一些关于方法名称的协议(无论是to_string、toString等)。我认为to_string是一个很好的选择,因为std已经为原始整数类型提供了这样的方法。 - Ahmed A
@AhmedA 运算符将是成员函数的名称 struct MyClass { operator std::string() const { return "MyClass"; } }; 这将允许您转换为字符串 MyClass mc; std::string s(mc); - Ryan Haining
显示剩余7条评论
4个回答

14
这种情况的标准做法是提供一个插入运算符,以便将对象插入到流中,而流可以是任何类型的流,例如stringstream。
如果您愿意,还可以提供一种将其转换为字符串的方法(对于插入运算符非常有用),如果您认为该转换可接受,则可以提供一个“to string”运算符。
以下是我的标准“point”类示例:
template <typename T>
struct point
{
  T x;
  T y;
  point(): x(), y() { }
  point( T x, T y ): x(x), y(y) { }
};

template <typename T>
std::ostream& operator << ( std::ostream& outs, const point <T> & p )
{
  return outs << "(" << p.x << "," << p.y << ")";
}

我也倾向于保留一个便利的函数,将事物转换为字符串:

template <typename T>
std::string to_string( const T& value )
{
  std::ostringstream ss;
  ss << value;
  return ss.str();
}

现在我可以轻松使用它:
int main()
{
  point p (2,-7);

  std::cout << "I have a point at " << p << ".\n";

  my_fn_which_takes_a_string( to_string(p) );

你会发现 Boost Lexical Cast Library也是为这种情况而设计的。
希望这能有所帮助。

4
C++标准并未规定如何实现此功能,但似乎有一个提案通用to_string/to_wstring函数可能会引入这样的选项,该提案在动机部分中还强调了当前普遍采用的做法(我在下面演示):
长期以来,C++程序员一直在寻找一种将对象转换为其字符串表示的简单方法。解决这个问题的典型答案是创建一个本地ostringstream,将对象插入流中,然后使用str成员函数获取结果字符串。虽然这种解决方案简单、安全、灵活和可扩展,但对于应该是单个函数调用的东西来说,它显然过于冗长。C++11提供了(部分)解决方案,即一组重载的to_string/to_wstring函数。不幸的是,这些仅限于内置数字类型。还存在非标准解决方案,最值得注意的是boost::lexical_cast,它提供了对象和字符串的双向转换,但缺乏任何格式控制。本文提出了一种解决方案,它:1.将现有的to_string/to_wstring函数推广到任何提供流输出运算符的类型和任何基本字符串特化;2.保持与这些函数的一致性和大部分兼容性;3.提供额外的格式化和连接能力;4.通过构建熟悉的ostringstream解决方案,具有概念上的简单性。

有两份旅行报告STL'sHerb Sutter's,但我没有在其中任何一篇中看到这篇论文被提及。希望在后-Kona邮件中会有涉及。

提案中提到的第一种方法可能类似于这个答案中的示例

class A {
public:
  int i;
};

std::ostream& operator<<(std::ostream &strm, const A &a) {
  return strm << "A(" << a.i << ")";
}

结合类似于示例从这里的内容:

template <typename T>
std::string to_string(const T& value) {
  std::ostringstream os;
  os << value;
  return os.str();
}

我们可以在问题Enabling Classes for Use with boost::lexical_cast中找到一个boost::lexical_cast的例子。

3

看起来没有标准的方式。据我了解,C++标准不允许重载std::to_string函数

我最终使用了以下两种解决方案之一:

解决方案 #1

您可以使用下面的方法代替toString()方法:

operator std::string() const {
    return "Object string.";
}

为了支持流,你可以添加类似下面的内容:

friend std::ostream & operator <<(std::ostream &out, const YourClass &obj) {
    return out << static_cast<std::string>(obj);
}

我希望"<<"运算符只是内联从第一个运算符的转换。

解决方案 #2

如果您通常以流式方式思考,也可以采用其他方式。
friend std::ostream & operator <<(std::ostream &out, const YourClass &obj) {
    out << "Object ";
    out << "string.";
    return out;
}

并在类型转换运算符中使用它:

operator std::string() const {
    std::ostringstream out;
    out << *this;
    return out.str();
}

不管怎样,这都可以为大多数情况提供解决方案。

1

C++标准是否提到定义方法to_string()以类似方式为类服务?

没有。

还是C++程序员遵循常见做法。

没有。但是,我怀疑每个项目都有类似的功能。名称和返回类型很可能取决于项目的编码指南。

在我的工作中,我们使用

virtual QString toString() const = 0;

在我们的基类中的一个。

您可以开始为您的项目使用类似的东西。

virtual std::string toString() const = 0;

在您的基类中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接