首页 > 解决方案 > C ++是否可以使用类变量作为默认参数

问题描述

我有一个树类,如下所示:

class avl
{
   node *root;
public:
    avl(int data){
      root->data = data;
    }

    int get_height(node *head = root){  //error here

        if (head->right == head->left) return 0;
        int l = get_height(head->left);
        int r = get_height(head->right);

        if (l > r) return l+1;
        return r+1;
     }
}

get_height不出所料,这会在定义处产生错误。g++ 将其抱怨为“对非静态数据成员的无效使用”。我可以修改这个问题还是应该在这里不雅地使用包装器。如果您可以在标准说明此错误原因的内容中添加一些详细信息,我将不胜感激。

标签: c++language-lawyerdefault-arguments

解决方案


不幸的是,这是不可能的。非静态类成员不能用作默认参数。

默认参数中不允许非静态类成员(即使它们没有被评估),除非用于形成指向成员的指针或成员访问表达式。

int b;
class X {
  int a;
  int mem1(int i = a); // error: non-static member cannot be used
  int mem2(int i = b); // OK: lookup finds X::b, the static member
  static int b;
};

从标准来看,[dcl.fct.default]/9

非静态成员不应出现在默认参数中,除非它作为类成员访问表达式 ( [expr.ref] ) 的id 表达式出现,或者除非它用于形成指向成员的指针 ( [expr.unary.操作])。[示例:以下示例中的声明格式错误,因为没有为用作初始值设定项的非静态成员提供对象。X​::​mem1()X​::​a

int b;
class X {
  int a;
  int mem1(int i = a);              // error: non-static member a used as default argument
  int mem2(int i = b);              // OK;  use X​::​b
  static int b;
};

然而,声明X​::​mem2()是有意义的,因为不需要任何对象来访问static member X​::​b. 类、对象和成员在[class]中描述。—结束示例]

正如你所说,你可以添加一个重载的包装函数,比如

int get_height(node *head) {
    ...
}
int get_height() {
    return get_height(this->root);
}

推荐阅读