Here is the code:

void SaveChangesToFile(Dictionary const& dictionary, string const& dictionaryFileName) { ofstream dictionaryFile(dictionaryFileName); for (auto translation : dictionary) { dictionaryFile << translation.first << "|" << translation.second << "\n"; } } 

Can you please tell me what can be replaced in the code with std::transform ?

  • 2
    You can replace the for loop based on a range. - Vlad from Moscow

1 answer 1

To begin with, output to the stream needs to be formatted as an operator << :

 std::ostream& operator<<(std::ostream& os, const Translation& tr){ os << translation.first << "|" << translation.second; return os; } 

I don’t know what type of translation you have, so I leave it to your conscience.

Now the body of your function looks like this:

 void SaveChangesToFile(Dictionary const& dictionary, string const& dictionaryFileName){ ofstream dictionaryFile(dictionaryFileName); for (auto translation : dictionary){ dictionaryFile << translation << "\n"; } } 

At that moment I realized that I was not answering your question completely, because in the end the code would look like this:

 void SaveChangesToFile(Dictionary const& dictionary, string const& dictionaryFileName){ ofstream dictionaryFile(dictionaryFileName); std::copy(dictionary.begin(), dictionary.end(), std::ostream_iterator<Translation>(dictionaryFile, "\n")); } 

If you are satisfied with the solution using std::copy , you can stop there. If you need blood from the nose std::transform , then go the other way.

Let's write a functor that will convert the translation object into a string:

 struct ToString{ std::stringstream ss; inline std::string operator()(const Translation &tr) const{ ss << translation.first << "|" << translation.second; return ss.str(); } }; 

Again, I do not know what kind of Translation. Maybe you could do without std::stringstream .
Now you can use std::transform :

 void SaveChangesToFile(Dictionary const& dictionary, string const& dictionaryFileName){ ofstream dictionaryFile(dictionaryFileName); std::transform(dictionary.begin(), dictionary.end(), std::ostream_iterator<std::string>(dictionaryFile, "\n"), ToString()); } 

Let's sum up.
The full version with std::copy looks like this:

 std::ostream& operator<<(std::ostream& os, const Translation& tr){ os << translation.first << "|" << translation.second; return os; } void SaveChangesToFile(Dictionary const& dictionary, string const& dictionaryFileName){ ofstream dictionaryFile(dictionaryFileName); std::copy(dictionary.begin(), dictionary.end(), std::ostream_iterator<Translation>(dictionaryFile, "\n")); } 

The full version with std::std::transform looks like this:

 struct ToString{ std::stringstream ss; inline std::string operator()(const Translation &tr) const{ ss << translation.first << "|" << translation.second; return ss.str(); } }; void SaveChangesToFile(Dictionary const& dictionary, string const& dictionaryFileName){ ofstream dictionaryFile(dictionaryFileName); std::transform(dictionary.begin(), dictionary.end(), std::ostream_iterator<std::string>(dictionaryFile, "\n"), ToString()); } 

In my opinion, the code with std::copy is better. Firstly, it is shorter, and secondly, there is no unnecessary conversion of translation into a string.

  • Thank you so much, you helped me very much. - Kolya