вложенный шаблонный класс и функция в глобальном пространстве имен

Я работаю над шаблоном структуры данных Graph, который является вектором STL объектов GraphNode. Я определил класс GraphNode, вложенный в класс Graph, и когда я вызываю перегруженный оператор вставки для объекта GraphNode внутри перегруженного оператора вставки для объектов Graph, отчеты Visual Studio 15 (C ++),

(30): warning C4346: 'myGraph<T>::myGraphNode': dependent name is not a type
(30): note: prefix with 'typename' to indicate a type
(30): error C2061: syntax error: identifier 'myGraphNode'
(33): error C2805: binary 'operator <<' has too few parameters
template <typename T>
ostream& operator<<(ostream& strm, const myGraph<T>::myGraphNode& gn)

добавив слово typename ко второму формальному параметру

template <typename T>
ostream& operator<<(ostream& strm, typename const myGraph<T>::myGraphNode& gn)

Компилятор генерирует следующую ошибку

(49): error C2679: binary '<<': no operator found which takes a right-hand operand of type 'const myGraph<int>::myGraphNode' (or there is no acceptable conversion)

Я получаю ту же ошибку, если у меня есть имя типа const …. или имя типа const …

Для полноты здесь весь код несколько упрощен для этого поста.
Спасибо за любую помощь

#include <iostream>
#include <vector>
#include <string>

using namespace std;

typedef unsigned int uint;

template <typename T>
class myGraph {
public:
class myGraphNode {
public:
myGraphNode(T val = T());
T mData;
}; // end class myGraphNode

myGraph();

uint addGraphNode(T data);
vector<myGraphNode> mGraphNodes;
}; // end class myGraph//          myGraphNode
template <typename T>
myGraph<T>::myGraphNode::myGraphNode(T val) : mData(val) {}

template <typename T>
ostream& operator<<(ostream& strm, typename const myGraph<T>::myGraphNode& gn) {
strm << gn.mData << std::endl;
return strm;
}//          myGraph
template <typename T>
myGraph<T>::myGraph() {}

template <typename T>
uint myGraph<T>::addGraphNode(T data) {
myGraph<T>::myGraphNode node(data);
mGraphNodes.push_back(node);
}

template <typename T>
ostream& operator<<(ostream& strm, const myGraph<T>& g) {
for (uint i = 0; i < g.mGraphNodes.size(); ++i)
cout << g.mGraphNodes[i] << endl;
return strm;
} // end operator<<(...)

int main()
{
myGraph<int> g;
g.addGraphNode(3);
g.addGraphNode(5);
cout << g << endl;
return 0;
}

2

Решение

Во-первых, правильный синтаксис для объявления параметров должен быть

template <typename T>
ostream& operator<<(ostream& strm, const typename myGraph<T>::myGraphNode& gn)
//                                 ~~~~~ ~~~~~~~~

обращаться Вот для получения дополнительной информации.

Во-вторых, с приведенным выше объявлением, при попытке вызвать его в operator<< за myGraph<T> лайк cout << g.mGraphNodes[i] << endl;, T не может быть выведено из-за не выводимые контексты):

Спецификатор вложенного имени (все слева от оператора разрешения области: 🙂 типа, указанного с помощью квалифицированного идентификатора:

Это означает, что вы должны явно указать аргумент шаблона, например,

operator<<<T>(strm, g.mGraphNodes[i]);
//        ~~~

Но это безобразно. Для вашего случая вы можете просто реализовать operator<< за myGraph<T> лайк

template <typename T>
ostream& operator<<(ostream& strm, const myGraph<T>& g) {
for (uint i = 0; i < g.mGraphNodes.size(); ++i)
cout << g.mGraphNodes[i].mData << endl;
return strm;
}

Кстати: вы должны дать возвращаемое значение для myGraph<T>::addGraphNode,

1

Другие решения

Вывод типа шаблона соответствует только шаблонам. Он не инвертирует зависимые типы, потому что это (в общем случае) невозможно.

Способ решения этой проблемы — техника, которую я называю операторами Кенига.

friend std::ostream& operator<<(std::ostream& strm, const myGraphNode& gn) {
strm << gn.mData << std::endl;
return strm;
}

Поместите это в тело myGraphNode,

class myGraphNode {
public:
myGraphNode(T val = T());
T mData;
friend std::ostream& operator<<(std::ostream& strm, const myGraphNode& gn) {
strm << gn.mData << std::endl;
return strm;
}
}; // end class myGraphNode

Это не шаблонный оператор, внедряемый в окружающее пространство имен (только), доступное через ADL. Какие красивые слова для «это просто работает».

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector