2017-01-13 88 views
3

我正在編寫一個在C++中實現後綴trie的程序。我試圖聲明一個沒有參數的遞歸函數,但是需要將一個指針傳遞給它自己。帶指針的C++默認參數

我在cpp文件,其中節點是先前聲明的數據結構從而限定它

public: 
    string longestRepeat(Node*); 
在頭文件

,和

string Trie::longestRepeat(Node* start = &nodes[0]){ 
    string deepest = ""; 
    for(unsigned int i = 0; i < start->getEdges(); i++){ 
     string child_deepest = longestRepeat(start->getChild(i)); 
     if(child_deepest.length() > deepest.length()) 
      deepest = child_deepest; 
    } 
    return deepest; 
} 

但是在主函數中簡單地調用trie.longestRepeat()會導致錯誤「Trie::longestRepeat()沒有匹配的函數調用。候選者期望1個參數,0提供」。

回答

4

你需要把默認的參數在聲明(在頭文件),如果你把它放在第二個聲明(定義),它只會被調用看到第二個使用聲明:

struct Trie { 
    std::string longestRepeat(Node*); 
}; 

int main() { 
    Trie{}.longestRepeat(); // Error 
} 

std::string Trie::longestRepeat(Node *p = &nodes[0]) { } 

void g() { 
    Trie{}.longestRepeat(); // Ok 
} 

但你或許應該做的是創造的longestRepeat公版調用私人/保護版本&nodes[0]

struct Trie { 
    std::string longestRepeat() { // No arguments 
     longestRepeat_(&nodes[0]); 
    } 
private: 
    std::string longestRepeat_(Node *); // Real implementation 
}; 
+0

感謝您的支持。但是現在我收到一條錯誤消息,聲稱'longestRepeat()'是雄心勃勃的;由於某些原因,它不能在主函數中選擇兩者之一。 –

+0

@LukeCollins你在嘗試第一個還是第二個片段? – Holt

+0

我忘了下劃線! –

2

對於成員函數,可以在類外定義中聲明default argument,但只有在可以看到定義的tranlation單元中使用默認參數調用成員函數。

這意味着您可以將Trie::longestRepeat的定義移動到頭文件以修復錯誤。

或者讓事情變得更簡單,在聲明中聲明默認參數而不是定義。例如

// header 
public: 
    string longestRepeat(Node* start = &nodes[0]); 

// implementation 
string Trie::longestRepeat(Node* start) { 
    ... 
} 

對於非模板類的成員函數,默認參數 允許上外的類的定義,並且與由所述聲明的類的內部的 缺省參數被組合身體。

class C { 
    void f(int i = 3); 
    void g(int i, int j = 99); 
}; 
void C::f(int i = 3) {   // error: default argument already 
}        // specified in class scope 
void C::g(int i = 88, int j) { // OK: in this translation unit, 
}        // C::g can be called with no argument