Home print any struct in template function
Reply: 2

print any struct in template function

Joo
1#
Joo Published in 2018-02-13 13:17:56Z

I have 3 or more struct , and I want that I have one function for print any struct

for example :

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

and

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

I want print this struct ( A and B) with same function

like this :

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

any body help me?

user9335240
2#
user9335240 Reply to 2018-02-13 13:47:26Z

Also, another solution is to make a function called to_string for example (this is to directly convert your struct to string, but the performance is not good)

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

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

Then

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

This is not good for printing, for printing, use the C++ convention of implementing operator<<

But.

This have a disadvantage, when an subclass want to change the output format. It can't.

So

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();
    }
};

The function print is as is

Then

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

You will find now (after virtual functions), this will work for SubclassA. But if you tried the operator<< or the beginning of the solution (to_string without virtual), it will work for SubclassA as it was a vanilla A.

Then you would make something like that

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

Inside your Base class, like this:

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

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

Now try the printing function for A to be:

void tryPrintingAsA(const A &a) {
    cout << a;
}
Ivan
3#
Ivan Reply to 2018-02-13 13:21:15Z

Usual practice in C++ is to define operator<<(std::ostream &, const T &) for your type:

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

This should be done for each type you want to print and this function should be defined in the same namespace as that type.

After that, your data types can be printed to all output stream. This also allows things like boost::lexical_cast to work with your type as it prints value to std::stringstream internally.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.298517 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO