c++ - 使用模板化运算符<<输出集合的集合

标签 c++ templates vector output

我想通过运算符调用外部集合一次来输出集合的集合(在本例中是 vector 的 vector )<<

当我删除 ' ' 时它就起作用了来自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?了解更多相关信息。

关于c++ - 使用模板化运算符<<输出集合的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55747824/

相关文章:

C++ 构造函数初始化列表调用默认构造函数。为什么?

c++ - localtime() 比 gmtime() 多花费 24 倍 linux 上的性能问题

c++ - 从非类型模板参数推导值类型

c++ - "Cannot convert"成员函数指针问题

java - vector 的所有元素都替换为最后一个对象 - java

c++ - vector 删除不会 "erase"第一个元素

c++ - 指针和指向该指针的地址会导致相同的结果

c++ - Clang 和 g++ 对运算符重载的处理方式不同?

c++ - 从 Typelist 子集创建函数指针

c++ - 将 lower_bound 与 vector<pair<string, double>> 一起使用时出错