如何将std::vector的内容打印到屏幕上?
实现以下操作符<<的解决方案也很好:
template<container C, class T, String delim = ", ", String open = "[", String close = "]">
std::ostream & operator<<(std::ostream & o, const C<T> & x)
{
// ... What can I write here?
}
以下是目前为止我所做的,没有单独的函数:
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <sstream>
#include <cstdio>
using namespace std;
int main()
{
ifstream file("maze.txt");
if (file) {
vector<char> vec(istreambuf_iterator<char>(file), (istreambuf_iterator<char>()));
vector<char> path;
int x = 17;
char entrance = vec.at(16);
char firstsquare = vec.at(x);
if (entrance == 'S') {
path.push_back(entrance);
}
for (x = 17; isalpha(firstsquare); x++) {
path.push_back(firstsquare);
}
for (int i = 0; i < path.size(); i++) {
cout << path[i] << " ";
}
cout << endl;
return 0;
}
}
我将在这里添加另一个答案,因为我已经提出了与之前的方法不同的方法,那就是使用locale facet。
基本原理在这里
基本上你要做的是:
Create a class that derives from std::locale::facet. The slight downside is that you will need a compilation unit somewhere to hold its id. Let's call it MyPrettyVectorPrinter. You'd probably give it a better name, and also create ones for pair and map.
In your stream function, you check std::has_facet< MyPrettyVectorPrinter >
If that returns true, extract it with std::use_facet< MyPrettyVectorPrinter >( os.getloc() )
Your facet objects will have values for the delimiters and you can read them. If the facet isn't found, your print function (operator<<) provides default ones. Note you can do the same thing for reading a vector.
我喜欢这种方法,因为你可以使用默认打印,同时仍然能够使用自定义覆盖。
缺点是如果在多个项目中使用facet,则需要一个面向facet的库(因此不能仅仅是头文件),而且需要注意创建一个新的locale对象的开销。
我把这个作为一个新的解决方案来写,而不是修改我的另一个解决方案,因为我相信两种方法都是正确的,你可以选择。
for_each + lambda表达式怎么样:
#include <vector>
#include <algorithm>
// ...
std::vector<char> vec;
// ...
std::for_each(
vec.cbegin(),
vec.cend(),
[] (const char c) {std::cout << c << " ";}
);
// ...
当然,对于这个具体任务,基于范围的for是最优雅的解决方案,但它也提供了许多其他可能性。
解释
for_each算法接受一个输入范围和一个可调用对象,在范围的每个元素上调用该对象。输入范围由两个迭代器定义。可调用对象可以是一个函数、一个函数指针、一个重载()操作符的类的对象,或者在本例中是一个lambda表达式。此表达式的形参与vector中元素的类型匹配。
这个实现的美妙之处在于lambda表达式的强大功能——您可以使用这种方法做更多的事情,而不仅仅是打印向量。
我写了一个操作符<<,它输出任何可迭代对象,包括自定义容器、标准容器和具有已知边界的数组。需要c++ 11:
template<typename Container, typename =
std::enable_if_t<std::is_same_v<std::void_t<
decltype(static_cast<typename Container::const_iterator (*)(const Container&)>(&std::cbegin)),
decltype(static_cast<typename Container::const_iterator (*)(const Container&)>(&std::cend))>, void>
&& !std::is_same_v<std::string, Container>>>
std::ostream& operator<<(std::ostream& out, const Container &vec)
{
std::cout << "[ ";
for(const auto& t: vec){
std::cout << t << " ";
}
std::cout << "] ";
return out;
}