通用打印函数,可以处理列表和标量实体
Generic print function which behaves handles both lists as well as scalar entities?
我想写一个函数,我可以调用每当我需要打印的东西。然而,当打印矢量或列表时,我需要它的行为略有不同。此外,一个vector或list也可以包含另一个vector或list。
我的第一个方法是这样做的:
#include <iostream>
#include <list>
#include <vector>
using namespace std;
template <typename T>
void
print(const vector<T>& v) {
cout << "[";
bool isFirst = true;
for (const T& e : v) {
if (isFirst) isFirst = false;
else cout << ",";
print(e);
}
cout << "]";
}
template <typename T>
void
print(const list<T>& l) {
cout << "[";
bool isFirst = true;
for (const T& e : l) {
if (isFirst) isFirst = false;
else cout << ",";
print(e);
}
cout << "]";
}
template <typename T>
void
print(const T& v) {
cout << v;
}
int
main(int argc, char** argv) {
vector<int> v;
print(v);
return 0;
}
如你所见,打印向量和列表有很多重复的代码,但我不知道如何组合它们。在任何情况下,代码都无法编译,因为编译器试图将标量实体(例如int
)的打印与print
的第一个实现匹配,而不是最后一个实现:
g++ -std=c++11 test.cpp
test.cpp: In instantiation of ‘void print(const std::vector<T>&) [with T = int]’:
test.cpp:42:12: required from here
test.cpp:15:16: error: no matching function for call to ‘print(const int&)’
print(e);
^
test.cpp:15:16: note: candidate is:
test.cpp:9:1: note: template<class T> void print(const std::vector<T>&)
print(const vector<T>& v) {
^
test.cpp:9:1: note: template argument deduction/substitution failed:
test.cpp:15:16: note: mismatched types ‘const std::vector<T>’ and ‘const int’
print(e);
^
你知道怎么解决这个问题吗?
有许多简洁的解决方案,但有一个非常接近您的解决方案,没有重复,没有任何太聪明的东西,没有任何库函数,下面是
template <typename T>
void print_container(const T&);
template <typename T>
void print(const std::vector<T>& v) { print_container(v); }
template <typename T>
void print(const std::list<T>& l) { print_container(l); }
template <typename T>
void print(const T& e) { cout << e; }
template <typename T>
void print_container(const T& c) {
cout << "[";
bool isFirst = true;
for (const auto& e : c) {
if (isFirst) isFirst = false;
else cout << ",";
print(e);
}
cout << "]";
}
也许您应该遵循for_each算法的模式。点击链接查看如何定义该算法的示例。http://www.cplusplus.com/reference/algorithm/for_each/
如果你想要一个泛型的打印机,那么你应该倾向于使用迭代器作为算法的输入。那么,由哪个容器提供它们就没有区别了,你的函数甚至可以接受指向C数组的指针。更进一步,如果你想让它为用户定义类型工作,那么用户定义类型应该有重载流操作符来支持它们。
也看看这个,并考虑更多的选择。http://www.cplusplus.com/reference/iterator/ostream_iterator/
我不能在评论中发布这个,但这里是另一个答案的简化版本,其中包含一个主要用于测试。测试网址:http://www.compileonline.com/compile_cpp11_online.php
当然,您可能需要对其他类型(如双精度类型或用户定义类型)进行专门化。
#include <vector>
#include <list>
#include <iostream>
template <typename T>
void print_container(const T&);
template <typename T>
void print(const T& e) { std::cout << e; }
template <typename T>
void print_container(const T& c) {
std::cout << "[";
bool isFirst = true;
for (const auto& e : c) {
if (isFirst) isFirst = false;
else std::cout << ",";
print(e);
}
std::cout << "]";
}
int main()
{
std::vector<int> v = {0, 1, 3, 5, 7, 9};
std::list<int> l = {0, 1, 3, 5, 7, 9};
print_container(v);
print_container(l);
}
相关文章:
- 有人能帮我处理这个链接列表吗?C++
- 处理从列表中删除指向对象的指针的"healthy"方法是什么?
- 处理程序的模块列表中有一个错误的模块"WebSocketModule"
- 为什么调用单例类 Qt 消息处理程序成员函数会出现错误:缺少参数列表
- 元功能处理模板列表
- QML 列表视图和密钥导航 - 处理单个密钥事件
- 如何在变量函数参数列表中检测给定类型的参数的可用性,并在处理完所有参数后采取行动
- 如何使用同一链接列表一次处理各种类型的节点
- 实现对象列表时,如何处理动态分配
- 如何处理列表控制标头中的右键单击事件
- 使用C 中的链接列表的文件处理
- RCPP:处理包含列表的列表
- 如何处理R到RCPP中的列表
- C++列表处理:将最小值初始化为列表的第一个值
- 用于处理 3 个整数列表的数据结构
- 在SFML 2.0中使用迭代器处理列表之间的冲突
- 如何在c++中处理包含列表的嵌套数据结构
- 如何将QActions列表添加到QMenu并用单个插槽处理它们
- 变量参数列表如何在C++中处理重载对象
- 列表处理在Prolog中使用的c++接口