Structure to string in elegant way
Solution 1
Since struct
s have public
visibility, you can just inject a member function to the struct directly to do the trick, like this for example:
#include <iostream>
#include <string>
using namespace std;
struct movies_t {
string title;
int year;
string toString()
{
return "title = " + title + ", year = " + to_string(year);
}
};
int main()
{
struct movies_t m{"Odyssey", -800};
cout << m.toString() << endl;
}
Output:
title = Odyssey, year = -800
Solution 2
There are many ways to implement this. The one I favour is to provide an ADL free-function to_string and an overload of operator<<.
Namespace added for exposition of ADL:
#include <string>
#include <ostream>
#include <sstream>
#include <iostream>
namespace movie
{
struct movies_t {
std::string title;
int year;
};
std::ostream& operator<<(std::ostream& os, movies_t const& arg)
{
os << "title = " << arg.title << ", year = " << arg.year;
}
std::string to_string(movies_t const& arg)
{
std::ostringstream ss;
ss << arg;
return std::move(ss).str(); // enable efficiencies in c++17
}
}
int main()
{
auto m = movie::movies_t { "Star Wars", 1977 };
std::cout << m << '\n';
using std::to_string;
std::cout << to_string(m) << '\n';
}
Solution 3
You can make that member function const
to ensure only members marked mutable
are modifiable.
#include <iostream>
#include <sstream>
struct movies_t {
std::string title;
int year;
std::string _to_string() const {
std::ostringstream stream_out;
stream_out << "title: " << title << " year: " << year;
return stream_out.str();
}
std::string toString() const {
return "title = " + title + " year = " + std::to_string(year);
}
};
std::ostream& operator<<(std::ostream& stream_out, const movies_t& M) {
stream_out << M.title << " " << M.year;
return stream_out;
}
std::string _to_string(const movies_t M) {
std::ostringstream stream_out;
stream_out << M.title << " " << M.year;
return stream_out.str();
}
int main() {
movies_t N{"Friends", 1994};
std::cout << N << std::endl;
std::cout << _to_string(N) << std::endl;
std::cout << N._to_string() << std::endl;
std::cout << N.toString() << std::endl;
return 0;
}
Solution 4
If you can't edit the struct you might want to wrap another class around
class MoviesExpansion {
public:
MoviesExpansion(std::string title, int year) // Initialize movie in constructor
{
movies.title = title;
movies.year = year;
}
movies_t& getMovies() { return movies; } // To get the raw movie for passing to the library.
private:
movies_t movies; // The struct to add the additional functionality
std::string toString() // The function we want to add
{
return "title = " + movies.title + " | year = " + std::to_string(movies.year);
}
}
then you can do
int main()
{
MoviesExpansion myMovies("Movie Title", 2018); // Create MoviesExpansion containing an movies_t structure
std::cout << myMovies.toString(); // Outputs "title = Movie Title | year = 2018"
someCompiledLibraryFunction(myMovies.getMovies()); //Call lib function
myMovies.getMovies().title = "New Title"; // Change Movie Title
std::cout << myMovies.toString(); // Outputs "title = New Title | year = 2018"
return 1;
}
Related videos on Youtube
vico
Updated on September 15, 2022Comments
-
vico over 1 year
I have structure:
struct movies_t { string title; int year; }
I would like this structure to have behavior to show it's fields in string.
std:string toString() { return "title=" title + "year="+ itostr(year); }
I can't change struct to class since I should pass it to compiled library which code is unknown. What is the best way to implement this?
-
UnholySheep about 6 yearsShow its fields in string where? For
ostream
like objects you can just overloadoperator<<
-
Some programmer dude about 6 yearsIn C++ the only different between a
struct
and aclass
is the default visibility (public
forstruct
,private
forclass
). That's it. So nothing stops you from making a member function. -
default about 6 yearswhat's wrong with the function you have now?
-
Daniel H about 6 yearsYour suggested
toString
function would produce something like"title=Harry Potter and the Philosopher's Stoneyear=1998"
, which is probably not the format you want.
-