Вот цель (код упрощен, конечно):Класс, который содержит набор себя с пользовательской компаратором - циклическая ссылка
#include <set>
struct Node
{
int Value;
std::set<Node*, CompareNodes> Children;
};
struct CompareNodes
{
bool operator()(const Node* l, const Node* r)
{
return l->Value < r->Value;
}
};
Но это не компилируется; тип CompareNodes
неизвестен, когда он встречается внутри Node
. Я мог бы изменить порядок, но тогда у меня есть противоположная проблема: Node
будет неизвестен, когда он встречается внутри CompareNodes
. Переадресация декларации не помогает в любом случае, потому что каждый тип использует другое так, как требуется его полное определение. Уродливое обходное решение таково:
#include <set>
template<typename T>
struct CompareNodes
{
bool operator()(const T* l, const T* r)
{
return l->Value < r->Value;
}
};
struct Node
{
int Value;
std::set<Node*, CompareNodes<Node>> Children;
};
Есть ли лучший способ? Бонусные очки, если ответ будет работать, даже если Node
является внутренним классом.
Вы все равно не можете делать стандартные контейнеры библиотеки неполных типов, по крайней мере, не переносимыми. – juanchopanza
На простом английском языке у вас не может быть класса, который содержит набор сам по себе. – juanchopanza
@juanchopanza Hm. Он может быть не переносимым, но мой компилятор позволяет это. Он все еще считается неполным, если я изменю его на 'std :: set'? –
dlf