2017-01-13 5 views
3

Я пишу программу, которая реализует суффикс trie в C++. Я пытаюсь объявить рекурсивную функцию без параметров, но которая должна передать указатель на себя.C++ Default Аргумент с указателями

я определяю его, таким образом,

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

в файле .cpp, где узел является предварительно объявленной структуры данных.

Однако при простом вызове 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 может быть объявлен по определению вне класса, но вызов функции-члена с использованием аргумента по умолчанию возможен только в блоке трансакций, который мог бы видеть определение.

Это значит, что для исправления ошибки вы можете переместить определение 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