我试图编写一个我需要打印时可以调用的函数。但是,在打印矢量或列表时,我需要它的行为略有不同。此外,矢量或列表可以包含另一个矢量或列表。
我的第一个方法是做这样的事情:
#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);
^
我知道怎么解决这个问题吗?
答案 0 :(得分:4)
有许多简洁的解决方案,但是一个非常接近你的解决方案没有重复,没有任何太聪明且没有任何库函数的是以下
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 << "]";
}
答案 1 :(得分:0)
也许您应该遵循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);
}