Проблема в том, что 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 ++; функция с произвольным типом контейнера, как его определить? , чтобы узнать больше об этом.