Поскольку setw
и width
не приводят к постоянной настройке, одним из решений является определение типа, который переопределяет operator<<
, применяя setw
перед значением. Это позволило бы ostream_iterator
для этого типа функционировать с std::copy
, как показано ниже.
int fieldWidth = 4;
std::copy(v.begin(), v.end(),
std::ostream_iterator< FixedWidthVal<int,fieldWidth> >(std::cout, ","));
Вы можете определить: (1) FixedWidthVal
как шаблонный класс с параметрами для типа данных (typename
) и ширины (значения) и (2) operator<<
для ostream
и FixedWidthVal
применяется setw
для каждой вставки .
// FixedWidthVal.hpp
#include <iomanip>
template <typename T, int W>
struct FixedWidthVal
{
FixedWidthVal(T v_) : v(v_) {}
T v;
};
template <typename T, int W>
std::ostream& operator<< (std::ostream& ostr, const FixedWidthVal<T,W> &fwv)
{
return ostr << std::setw(W) << fwv.v;
}
Тогда его можно применить с помощью std::copy
(или петли for
):
// fixedWidthTest.cpp
#include <iostream>
#include <algorithm>
#include <iterator>
#include "FixedWidthVal.hpp"
int main () {
// output array of values
int array[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256 };
std::copy(array,array+sizeof(array)/sizeof(int),
std::ostream_iterator< FixedWidthVal<int,4> >(std::cout, ","));
std::cout << std::endl;
// output values computed in loop
std::ostream_iterator<FixedWidthVal<int, 4> > osi(std::cout, ",");
for (int i=1; i<4097; i*=2)
osi = i; // * and ++ not necessary
std::cout << std::endl;
return 0;
}
Выход ( демо )
1, 2, 4, 8, 16, 32, 64, 128, 256,
1, 2, 4, 8, 16, 32, 64, 128, 256, 512,1024,2048,4096,