在模板函数中打印任何结构

时间:2018-02-13 13:17:57

标签: c++ templates struct

我有3个或更多结构,我希望我有一个函数用于打印任何结构

例如:

struct A 
{
  int a0;
  string a1;
  bool a2;
}

struct B
{
 CString b0;
 double b1;
 int b2;
 string b3
}

我想打印具有相同功能的结构(A和B)

像这样:

template<typename T>
inline void print(T)
{
  std::cout << // I don't know what is write here....
}

任何人帮助我?

2 个答案:

答案 0 :(得分:4)

C ++中的常规做法是为您的类型定义operator<<(std::ostream &, const T &)

std::ostream &operator<<(std::ostream &os, const A &value)
{
    // print here
    return os;
}

应该为要打印的每种类型执行此操作,并且应在与该类型相同的命名空间中定义此函数。

之后,您的数据类型可以打印到所有输出流。这也允许boost::lexical_cast之类的内容与您的类型一起使用,因为它会在内部将值打印到std::stringstream

答案 1 :(得分:1)

另外,另一个解决方案是创建一个名为to_string的函数(这是将结构直接转换为字符串,但性能不佳)

struct A
{
  int a0;
  string a1;
  bool a2;

  string to_string() const {
      return "{ " + std::to_string(a0) + ", " + a1 + ", " + (a2 ? "true" : "false") + " }";
  }
};

然后

template<typename T>
void print(const T &a) {
    cout << a.to_string() << "\n";
}

这不适合打印,打印,使用实现operator<<

的C ++约定

但是

当子类想要更改输出格式时,这有一个缺点。它不能。

所以

class DynamicallyToStringConvertible {
public:
    virtual string to_string() const = 0;
    virtual ~DynamicallyToStringConvertible() {}
};

struct A: DynamicallyToStringConvertible
{
    ...
    virtual string to_string() const {
        return "{ " + std::to_string(a0) + ", " + a1 + ", " + (a2 ? "true" : "false") + " }";
    }
}

struct SubclassFromA: public A {
    virtual string to_string() const {
        return "Subclass: " + A::to_string();
    }
};

函数print按原样

然后

void tryPrintingAsA(const A &a) {
    print(a);
}

您现在可以找到(在虚函数之后),这将适用于SubclassA。 但是如果您尝试了operator<<或解决方案的开头(没有虚拟的to_string),它将适用于SubclassA,因为它是一个香草A。

然后你会做出类似的东西

friend ostream &operator<<(ostream &s, const DynamicallyToStringConvertible &p) {
    return s << p.to_string();
}

在Base类中,如下所示:

class DynamicallyToStringConvertible {
public:
    virtual string to_string() const = 0;
    virtual ~DynamicallyToStringConvertible() {}

    friend ostream &operator<<(ostream &s, const DynamicallyToStringConvertible &p) {
        return s << p.to_string();
    }
};

现在尝试A的打印功能:

void tryPrintingAsA(const A &a) {
    cout << a;
}