【问题标题】:C++ Default Argument with Pointers带指针的 C++ 默认参数
【发布时间】:2017-01-13 06:56:46
【问题描述】:

我正在编写一个在 C++ 中实现后缀 trie 的程序。我正在尝试声明一个没有参数的递归函数,但它需要传递一个指向自身的指针。

我是这样定义的

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 文件中,其中 node 是先前声明的数据结构。

但是,在主函数中简单地调用 trie.longestRepeat() 会导致错误“Trie::longestRepeat() 没有匹配的函数调用。候选人需要 1 个参数,提供 0 个”。

【问题讨论】:

    标签: c++ pointers recursion default-value suffix-tree


    【解决方案1】:

    你需要将默认参数放在声明中(在头文件中),如果你把它放在第二个声明(定义)中,它只会被调用看到第二个声明:

    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 的公共版本,它使用&amp;nodes[0] 调用私有/受保护版本:

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

    【讨论】:

    • 谢谢。但是现在我收到一条错误消息,声称longestRepeat() 是雄心勃勃的;由于某种原因,它无法在主函数中的两者之间进行选择。
    • @LukeCollins 你是在尝试第一个还是第二个 sn-p?
    • 我忘记了下划线!
    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-08
      • 2013-01-27
      相关资源
      最近更新 更多