2016-11-22 24 views
2

這裏的目標(代碼簡化,當然):類,它包含了一組本身就帶有自定義比較 - 循環引用

#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; 
    } 
}; 

但是,這並不編譯;遇到Node時遇到類型CompareNodes。我可以改變順序,但後來我遇到了相反的問題 - NodeCompareNodes內部遇到它時將是未知的。前向聲明在兩種情況下都不起作用,因爲每種類型都需要使用另一種類型的方式來定義完整的定義。一個醜陋的解決方法是:

#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是內部課程,如果答案仍然有效,獎勵分數。

+0

無論如何,您不能製作不完整類型的標準庫容器,至少不能移植。 – juanchopanza

+0

用簡單的英語,你不能有一個包含一組本身的類。 – juanchopanza

+0

@juanchopanza嗯。它可能不是可移植的,但我的編譯器允許它。如果我將其更改爲'std :: set ',它仍算作不完整類型嗎? – dlf

回答

3

你可以使用嵌套類作爲比較:

#include <set> 

struct Node 
{ 
    struct CompareNodes 
    { 
     bool operator()(const Node& l, const Node& r) 
     { 
     return l.Value < r.Value; 
     } 
    }; 

    int Value; 
    std::set<Node, CompareNodes> Children; 
}; 
2

向前聲明不會在任何情況下

不太真實的幫助。向前聲明會工作得很好:

#include <set> 

struct Node; 

struct CompareNodes 
{ 
    bool operator()(const Node& l, const Node& r); 
}; 

struct Node 
{ 
    int Value; 
    std::set<Node, CompareNodes> Children; 
}; 

bool CompareNodes::operator()(const Node& l, const Node& r) 
{ 
    return l.Value < r.Value; 
} 

如果operator()成員函數需要在頭文件中聲明,就必須堅持一個inline關鍵字它。

+0

Yikes;這應該是顯而易見的。我已經遠離C++太久...... – dlf

+3

我相信'sts :: set '需要'Node'是一個完整的類型?或者最近變化了嗎? – Yakk

1

也許你可以使用模板來延遲完整性檢查,直到使用?

#include <set> 

struct CompareNodes; 

template <class Cmp = CompareNodes> 
struct Node 
{ 
    int Value; 
    std::set<Node*, Cmp> Children; 
}; 

struct CompareNodes 
{ 
    bool operator()(const Node<>* l, const Node<>* r) 
    { 
     return l->Value < r->Value; 
    } 
}; 

int main() { 
    Node<> n; 
}