我想通过运算符<<一次调用外部集合来输出集合的集合(在这种情况下是向量的向量)
当我从' '
函数中删除operator<<()
时,它可以工作,但我希望每行的每个输出元素之间都有一个空格。我尝试用' '
(也包括字符串头文件)替换" "
但得到相同的错误。
有办法解决这个问题吗?
#include <iostream>
#include <vector>
using namespace std;
vector<vector<bool>> lookup(10, vector<bool>(10, true));
template <typename T>
ostream& operator<< (ostream& out, const T& collection)
{
for (const auto& elem : collection)
out << elem << ' ';
return out << endl;
}
int main()
{
cout << lookup << endl;
}
我收到以下错误:
1>------ Build started: Project: test, Configuration: Debug Win32 ------
1>test.cpp
1>c:\users\user\source\repos\codechef\practice\beginner\test\test\test.cpp(16): error C2593: 'operator <<' is ambiguous
1>c:\users\user\source\repos\codechef\practice\beginner\test\test\test.cpp(13): note: could be 'std::ostream &operator <<<char>(std::ostream &,const T &)'
1> with
1> [
1> T=char
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\ostream(921): note: or 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,_Elem)'
1> with
1> [
1> _Elem=char
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\ostream(834): note: or 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,char)'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\ostream(749): note: or 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,char)'
1>c:\users\user\source\repos\codechef\practice\beginner\test\test\test.cpp(16): note: while trying to match the argument list '(std::ostream, char)'
1>c:\users\user\source\repos\codechef\practice\beginner\test\test\test.cpp(22): note: see reference to function template instantiation 'std::ostream &operator <<<std::vector<std::vector<bool,std::allocator<_Ty>>,std::allocator<std::vector<_Ty,std::allocator<_Ty>>>>>(std::ostream &,const T &)' being compiled
1> with
1> [
1> _Ty=bool,
1> T=std::vector<std::vector<bool,std::allocator<bool>>,std::allocator<std::vector<bool,std::allocator<bool>>>>
1> ]
1>Done building project "test.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
问题是模板中的T
不限于特定类型或类型范围。编译器可以用它想要的任何类型替换它。
当你写out << ' ';
编译器寻找函数ostream& operator<< (ostream& out, const char& collection)
,它找到两个这样的函数。其中一个来自标准库,另一个是您的功能。编译器无法决定它应该使用哪个版本,所以它只是停止编译。
要解决此问题,您需要限制模板,以便它不接受您不需要的类型。这样做的一种方法是制作一个只接受vector
的模板:
#include <iostream>
#include <vector>
using namespace std;
vector<vector<bool>> lookup(10, vector<bool>(10, true));
template <typename T>
ostream& operator<< (ostream& out, const vector<T>& collection)
{
for (const auto& elem : collection)
out << elem << ' ';
return out << endl;
}
int main()
{
cout << lookup << endl;
}
如果您需要为更多类型的容器定义此函数,而不是多次复制它,您可以创建一个接受所有类型的模板,但它没有与标准库冲突的名称。然后你可以创建一些只调用你的通用函数的operator<<
的简单实例。
#include <iostream>
#include <vector>
#include <array>
using namespace std;
vector<vector<bool>> lookup(10, vector<bool>(10, true));
template <typename T>
ostream& printCollection (ostream& out, const T& collection)
{
for (const auto& elem : collection)
out << elem << ' ';
return out << endl;
}
template <typename T>
ostream& operator<< (ostream& out, const vector<T>& collection)
{
return printCollection(out, collection);
}
template <typename T, size_t N>
ostream& operator<< (ostream& out, const array<T, N>& collection)
{
return printCollection(out, collection);
}
int main()
{
cout << lookup << endl;
}
我认为,如果不单独为每种类型的容器定义功能,甚至是可能的。但是,它需要一些高级模板魔法。你可以阅读这个c++ template class; function with arbitrary container type, how to define it?来了解更多相关信息。