c++11 - c++里面类成员为什么不能做为类成员函数的默认实参?
伊谢尔伦
伊谢尔伦 2017-04-17 13:33:09
0
4
600
class TestClass
{
public:
    TestClass() = default;
    ~TestClass() = default;

public:
    int func(int j = i)
    {
        cout << i << endl;
    }

private:
    int i = 1;
};

比如这样 这样会报错 为什么?

伊谢尔伦
伊谢尔伦

小伙看你根骨奇佳,潜力无限,来学PHP伐。

reply all(4)
PHPzhong

Some parts of the original answer are wrong, please answer again.

Static variables can be used as default arguments and do not need to be constants. Examples are as follows:

#include <iostream>

class A {
public:
    explicit A(int mm = n) : m(mm) {}
    int get() const { return m; }
    int foo(int i = n) const { return i; }
    static void set(int nn) { n = nn; }

private:
    int m;
    static int n;
};

int A::n = 1;

int main() {
    A a1;
    A a2(2);
    std::cout << "a1: foo() " << a1.foo() << " get() " << a1.get() << std::endl;
    std::cout << "a2: foo() " << a2.foo() << " get() " << a2.get() << std::endl;
    A::set(3);  //a1.set(3);  //a2.set(3);
    std::cout << "A::set(3)" << std::endl;
    std::cout << "a1: foo() " << a1.foo() << " get() " << a1.get() << std::endl;
    std::cout << "a2: foo() " << a2.foo() << " get() " << a2.get() << std::endl;
    A a3;
    std::cout << "a3: foo() " << a3.foo() << " get() " << a3.get() << std::endl;
    
    return 0;
}

Original answer

Static constants are OK, such as the following two definitions.

static const int i;
static constexpr int i;

Of course, the initialization of static constants is another matter.

For specific examples, please refer to "C++ Primer" Fifth Edition, Section 7.6, the part related to the use of static members.

刘奇

This is not possible in C++. Although C++ stipulates the order in which parameters are pushed onto the stack, the standard does not stipulate the order in which parameters are initialized. I think this is the biggest reason. You can’t do this like this

int func(int m, int n = m); // 这中写法不行,包括上面你例子中的j = this->i,
//个人觉得还有一个原因就是this或者m是最后压栈的,
//n = m或者j = this->i 并不能访问到m或者this

int func(int m = n, int n = 10); //虽然说理论上n是比m会早一步压人栈中,
//但是因为没有规定初始化顺序所以这种写法不对

And this way of writing is probably very troublesome when generating code during compilation. The default parameters can use static or literal values
Some other languages ​​support this way of writing using non-static members

Post a paragraph of standards

ISO C++ section 8.3.6/9
a nonstatic member shall not be used in a default argument expression, even if it is 
not evaluated, unless it appears as the id-expression of a class member access 
expression (5.2.5) or unless it is used to form a pointer to member (5.3.1).
ISO C++ section 8.3.6/9
Default arguments are evaluated each time the function is called. The order of 
evaluation of function arguments is unspecified. Consequently, parameters of a function
shall not be used in default argument expressions, even if they are not evaluated.

Of course there is a good solution, using overloading

int func(int j);
int func()
{
    func(this->i);
}
  • Reference

    http://stackoverflow.com/questions/4539406/nonstatic-member-as-a-default-argument-of-a-nonstatic-member-function
巴扎黑

Because when func(int j = i), this is the zeroth parameter, and the first parameter cannot see this, naturally there is no way to get this->i, just like:

class A {
public:
    int a = 1;
};
class B {
public:
    int func(A* a, int j = a->i) {
    //do something
    }
};

int main(){
    A a;
    B b;
    b.func(&a);
}

The second parameter of func here cannot use the a in the first parameter.

黄舟
class TestClass
{
public:
    TestClass() = default;
    ~TestClass() = default;

public:
    int func(int j = i)
    {
        cout << i << endl;
    }

private:
    int i = 1; //这里
};

Member variables can be the default arguments of member functions. The problem with your error is not here. There is a problem with the initialization of your member variables.
It is wrong to initialize the member variable in the definition.

You can only define member variables or initialize static variables under private. The initialization of ordinary member variables is completed in the constructor.



class TestClass
{
public:
    TestClass():i(1){};

public:
    int func(int j = i)
    {
        cout << i << endl;
    }

private:
    int i;
};
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template