这个例子:
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
int v[] = { 1, 2, 3 };
std::copy( &v[0], &v[3], std::ostream_iterator< int >( std::cout, "\n " ) );
}
产生下一个输出:
1
2
3
有没有办法更改示例以使其产生下一个输出?
1
2
3
PS我知道我可以使用for循环,但我对使用算法和迭代器的解决方案感兴趣。
答案 0 :(得分:3)
如果你想使用C ++ 11,你可以使用lambda。
就像这样:
int v[] = { 1, 2, 3};
std::for_each( &v[0], &v[3], [](int i){ std::cout << " " << i << "\n";} );
答案 1 :(得分:3)
使用std::cout << " "
代替std::cout
:
std::copy(v, v+3, std::ostream_iterator<int>(std::cout << " ", "\n " ) );
此处,表达式std::cout << " "
首先计算将单个空间打印到输出的位置,并将评估值std::ostream&
传递给std::ostream_iterator
现在输出将正确对齐:
1
2
3
工作代码:http://www.ideone.com/kSdpk
顺便说一下,不要写&v[3]
。这会调用Undefined bevahior。写v+3
。
答案 2 :(得分:3)
使用std::ostream_iterator
无法执行此操作。 (恕我直言,应该
是的,但它不存在。)如果你不介意写一个额外的小
功能或类,
您可以使用std::transform
,例如:
struct FormatString
{
std::string operator()( std::string const& original ) const
{
return ' ' + original + '\n';
}
};
// ...
std::transform(
v.begin(), v.end(),
std::ostream_iterator<std::string>( std::cout ),
FormatString() );
如果你有C ++ 11,你可以使用lambda作为FormatString
。
我发现这种情况的需要经常发生,我写了一篇
PatsubstTransformer
- 基本上是一个功能对象
实现GNU make的$(patsubst...)
函数。所以我愿意
必须写:
std::transform(
v.begin(), v.end(),
std::ostream_iterator<std::string>( std::cout ),
PatsubstTransformer( "%", " %\n" ) );
我发现我经常使用它。 (我还发现更多使用std::transform
适合于std::copy
,因为我输出的是a
转化。)
答案 3 :(得分:2)
在std::copy
之前输出一个空格。
答案 4 :(得分:2)
不,不是真的。 ostream_iterator
不可配置。
所以你必须使用其他答案中的前置空间“变通方法”,并手动砍掉最后一行。
BTW It's been noted严格来说,&v[3]
由于子表达式v[3]
中的隐式解除引用而调用未定义的行为。首选&v[0]+3
(或只是v+3
) - “拥有”一个指向一个数组末尾的指针是可以的,只要它没有被解除引用。
您可以制作自己的类ostream_iterator
来执行此操作,如以下示例所示。
是的,它很冗长;但是,您也可以根据自己不断变化的需求进行更改:
#include <iostream>
#include <iterator>
#include <algorithm>
template <class T, class charT = char, class traits = std::char_traits<charT> >
struct ostream_iterator_x
: std::iterator<std::output_iterator_tag, void, void, void, void> {
typedef charT char_type;
typedef traits traits_type;
typedef std::basic_ostream<charT,traits> ostream_type;
ostream_iterator_x(ostream_type& s, const charT* pre = 0, const charT* post = 0)
: s(s)
, pre(pre)
, post(post) {};
ostream_iterator_x(const ostream_iterator_x& x)
: s(x.s)
, pre(x.pre)
, post(x.post) {};
~ostream_iterator_x() {}
ostream_iterator_x& operator=(const T& value) {
if (pre != 0) s << pre;
s << value;
if (post != 0) s << post;
return *this;
}
ostream_iterator_x& operator*() { return *this; }
ostream_iterator_x& operator++() { return *this; }
ostream_iterator_x& operator++(int) { return *this; }
private:
ostream_type& s;
const charT* pre;
const charT* post;
};
int main()
{
int v[] = { 1, 2, 3 };
std::copy(v, v+3, ostream_iterator_x<int>(std::cout, " ", "\n"));
}
// Output:
// 1
// 2
// 3
(我使用[n3290: 24.6/2]
来确定此工作所需的成员和基本规范,并且符合标准。)