I'd like to display a vector (implemented in my custom Vector class) and have the output width of the elements be configurable. I've done this by creating a simple wrapper for the element being displayed which stores the desired width in a static field. I'm not sure if this is the best approach. Any other suggestions would be much appreciated.
/** A struct for formatting doubles with a fixed width. */
struct FixedWidthDouble {
FixedWidthDouble(double x) : x_(x) {}
double x_;
static int width_;
};
/** Apply a fixed width manipulator to a double for display. */
std::ostream& operator<<(std::ostream& out,
const FixedWidthDouble &fixedWidthDouble) {
return out << std::setw(fixedWidthDouble.width_) << fixedWidthDouble.x_;
}
Here's an example of it being applied:
/** Convert a Vector into a stream suitable for display. */
std::ostream& Vector::Print(std::ostream& out, int width) const {
out << "[" << std::setprecision(1) << std::fixed;
FixedWidthDouble::width_ = width;
std::copy(begin(), end(), std::ostream_iterator<FixedWidthDouble>(out, " "));
return out << " ]";
}
Is there a cleaner way to do this?
Proposed Solution
Based on feedback from Begemoth this is the solution I decided to go with. Does this look reasonable?
template<int width>
struct FixedWidthDouble {
FixedWidthDouble(double x) : x_(x) {}
double x_;
};
/** Apply a fixed width manipulator to a double for display. */
template <int width>
std::ostream& operator<<(std::ostream& out,
const FixedWidthDouble<width> &fixedWidthDouble) {
return out << std::setw(width) << fixedWidthDouble.x_;
}
/** Convert a Vector into a stream suitable for display. */
template <int width>
std::ostream& Vector::Print(std::ostream& out) const {
out << "[" << std::setprecision(1) << std::fixed;
std::copy(begin(), end(),
std::ostream_iterator<FixedWidthDouble<width> >(out, " "));
return out << " ]";
}