C++:打印或计算一个标准库容器到控制台
C++: Printing or cout a standard library container to console
打印或cout
C++ 标准库容器到控制台以查看其内容的 C++ 方法是什么?
另外,为什么 C++ 库实际上没有为您重载 <<
运算符?它背后有什么历史吗?
最简单的方法是使用基于范围的for语句。例如
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
template <class Container>
std::ostream & display( const Container &container,
const char *s = " ",
std::ostream &os = std::cout )
{
for ( const auto &value : container )
{
os << value << s;
}
return os;
}
int main()
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> v( std::begin( a ), std::end( a ) );
display( a, "; " );
std::cout << std::endl;
display( v );
std::cout << std::endl;
return 0;
}
程序输出为
0; 1; 2; 3; 4; 5; 6; 7; 8; 9;
0 1 2 3 4 5 6 7 8 9
然而,更灵活的方法是使用标准算法 std::copy
。在这种情况下,您可以自己设置显示范围并使用反向迭代器。
您也可以编写函数,使其获得更多信息。
why doesn't the C++ library actually overload the << operator for you?
因为任何用户都可以使用自己的方法来输出容器,正如您从我的演示程序的输出中看到的那样。实际上容器是用户定义的 class 并且应该重载运算符 << 的是用户。 std::string 和 std::bitset 有例外,但字符串和位集作为一个实体输出,与基本类型类似,没有中间分隔符。
为 ostream
重载 operator<<
是可行的方法。这是一种可能性:
template <class container>
std::ostream& operator<<(std::ostream& os, const container& c)
{
std::copy(c.begin(),
c.end(),
std::ostream_iterator<typename container::value_type>(os, " "));
return os;
}
那么你可以简单地写:
std::cout << SomeContainer << std::endl;
这里有一些其他非常好的解决方案:Pretty-print C++ STL containers
为了多样化,做一个适配器,比如
template< typename T >
struct SequencePrinter
{
const T& t;
// ...
};
template< typename T >
SequencePrinter<T> sequence_printer(const T&);
template< typename T >
ostream& operator<<(ostream&, SequencePrinter<T>);
int main() {
vector<int> v;
// ...
cout << sequence_printer(v) << endl;
}
这允许使用通常的 <<
表示法,但不会尝试强制选择 <<
对序列的含义。当然,它也可以变得相当可配置。
打印或cout
C++ 标准库容器到控制台以查看其内容的 C++ 方法是什么?
另外,为什么 C++ 库实际上没有为您重载 <<
运算符?它背后有什么历史吗?
最简单的方法是使用基于范围的for语句。例如
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
template <class Container>
std::ostream & display( const Container &container,
const char *s = " ",
std::ostream &os = std::cout )
{
for ( const auto &value : container )
{
os << value << s;
}
return os;
}
int main()
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> v( std::begin( a ), std::end( a ) );
display( a, "; " );
std::cout << std::endl;
display( v );
std::cout << std::endl;
return 0;
}
程序输出为
0; 1; 2; 3; 4; 5; 6; 7; 8; 9;
0 1 2 3 4 5 6 7 8 9
然而,更灵活的方法是使用标准算法 std::copy
。在这种情况下,您可以自己设置显示范围并使用反向迭代器。
您也可以编写函数,使其获得更多信息。
why doesn't the C++ library actually overload the << operator for you?
因为任何用户都可以使用自己的方法来输出容器,正如您从我的演示程序的输出中看到的那样。实际上容器是用户定义的 class 并且应该重载运算符 << 的是用户。 std::string 和 std::bitset 有例外,但字符串和位集作为一个实体输出,与基本类型类似,没有中间分隔符。
为 ostream
重载 operator<<
是可行的方法。这是一种可能性:
template <class container>
std::ostream& operator<<(std::ostream& os, const container& c)
{
std::copy(c.begin(),
c.end(),
std::ostream_iterator<typename container::value_type>(os, " "));
return os;
}
那么你可以简单地写:
std::cout << SomeContainer << std::endl;
这里有一些其他非常好的解决方案:Pretty-print C++ STL containers
为了多样化,做一个适配器,比如
template< typename T >
struct SequencePrinter
{
const T& t;
// ...
};
template< typename T >
SequencePrinter<T> sequence_printer(const T&);
template< typename T >
ostream& operator<<(ostream&, SequencePrinter<T>);
int main() {
vector<int> v;
// ...
cout << sequence_printer(v) << endl;
}
这允许使用通常的 <<
表示法,但不会尝试强制选择 <<
对序列的含义。当然,它也可以变得相当可配置。