是否有将类转换为字符串的标准方法

时间:2015-10-26 23:39:01

标签: c++ c++11

在Java中,标准是定义方法toString()以返回类的字符串表示。除了重载operator<<之外,C ++中是否有这样的标准?我知道有std::to_string()方法来获取数字的字符串表示。 C ++标准是否谈到定义方法to_string()以便为类提供类似的目的,或者C ++程序员是否遵循通用的做法?

4 个答案:

答案 0 :(得分:7)

执行此类操作的标准方法是提供插入运算符,以便可以将对象插入到流中 - 可以是任何类型的流,例如字符串流。

如果您愿意,还可以提供转换为字符串的方法(对插入运算符很有用),如果发现转换可以接受,则可以提供“to string”运算符。

这是我标准的'点'类示例:

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也是为这种事情设计的。

希望这有帮助。

答案 1 :(得分:4)

C ++标准没有规定这样做的方法,但看起来有一个提案可能会引入这样一个选项Generic to_string/to_wstring functions,它在动机部分中说明了当前的普遍做法(< em>我在下面演示):

  

很长一段时间以来,C ++程序员一直在寻找一种简单的方法   将对象转换为其字符串表示形式。 一个典型的答案   这个问题是创建一个本地ostringstream,插入对象   进入流,然后用str获取结果字符串   会员职能。该解决方案简单,安全,灵活   可扩展的,虽然对于某些东西来说肯定过于冗长   应该是一个单一的函数调用。 C ++ 11提供(部分)   一组重载的to_string / to_wstring形式的解决方案   功能。不幸的是,这些仅限于内置   数字类型。 非标准解决方案也存在 - 最值得注意的是   boost :: lexical_cast,它提供对象的双向转换   字符串,但没有任何格式控制

     

本文提出了一个解决方案:

     
      
  • 概括了现有的to_string / to_wstring函数,用于提供流输出运算符和任何basic_string的任何类型   专业化,
  •   
  • 保持一致且大部分与这些功能兼容,
  •   
  • 提供额外的格式和连接功能,
  •   
  • 在概念上很简单,建立在熟悉的ostringstream解决方案之上。
  •   

有两个旅行报告STL'sHerb Sutter's,我也没有看到这篇论文。所以希望post-Kona邮件出现时会有这个内容。

他们在提案中提到的第一种方法看起来像the example in this answer

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

结合类似于示例from here的内容:

boost::lexical_cast

我们可以在问题Enabling Classes for Use with boost::lexical_cast中找到having示例。

答案 2 :(得分:1)

  

C ++标准是否说定义方法to_string()以便为类提供类似的用途,

没有

  

或者C ++程序员是否遵循惯例。

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

在我的工作中,我们使用

import os                                                      
import csv                                                     
dataList = []                                                  
with open("table.csv") as csv_file:                         
data_reader = csv.reader(csv_file, dialect='excel-tab')        
for rows in data_reader:                                       
    if float(rows[2]) <= 0.20:                                 
        if float(rows[0]) <= 10:                               
           print(rows)                                       
        if 10 <float(rows[0])<=20:                            
            print (rows)

在我们的一个基类中。

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

if 20<float(rows[2])<= 30:

在您的基类中。

答案 3 :(得分:1)

好像没有标准方法,但是我最终使用了以下两种解决方案之一:

解决方案#1

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

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

要支持流,您可以添加以下内容:

friend std::ostream & operator << (std::ostream &out, const YourClass &obj) {
    return out << (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();
}

无论哪种方式,在大多数情况下,您都可以使用。