Reputation: 16640
This is an academic question.
sdt::mutex m;
typedef std::lock_guard<std::mutex> G;
void thread1(){
G g(m);
std::cout << std::setw(9);
std::cout << 3.14;
std::cout << std::endl;
}
void thread2(){
G g(m);
std::cout << std::setw(7);
std::cout << 3.14;
std::cout << std::endl;
}
My problem is that the formatting is bound to the output stream, so I need to set all the formatting options ever invented on my thread if I want to be sure about the output I produce. Which will or will not work next year.
std::ostringstream
locally on my thread and write oss.str()
to std::cout
?Upvotes: 2
Views: 153
Reputation: 69882
I've used boost for brevity but you could write your own optional and state saver.
#include <mutex>
#include <iostream>
#include <iomanip>
#include <tuple>
#include <utility>
#include <boost/io/ios_state.hpp>
#include <boost/optional.hpp>
std::mutex m;
struct save_and_lock
{
boost::optional<boost::io::ios_all_saver> saver;
std::unique_lock<std::mutex> lock;
void init(std::ostream& os)
{
lock = std::unique_lock<std::mutex>(m);
saver.emplace(os);
os.flags(std::ios_base::fmtflags(0));
}
friend std::ostream& operator<<(std::ostream& os, save_and_lock&& s)
{
s.init(os);
return os;
}
};
void thread1(){
std::cout << save_and_lock() << std::setw(9) << 3.14 << std::endl;
}
void thread2(){
std::cout << save_and_lock() << std::setw(9) << 3.14 << std::endl;
}
This will work because the evaluation order of user-defined operator <<
is left to right.
Upvotes: 2