search

Home  >  Q&A  >  body text

c++11 - c++里面类成员为什么不能做为类成员函数的默认实参?

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

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

private:
    int i = 1;
};

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

伊谢尔伦伊谢尔伦2767 days ago584

reply all(4)I'll reply

  • PHPz

    PHPz2017-04-17 13:35:09

    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.

    reply
    0
  • 怪我咯

    怪我咯2017-04-17 13:35:09

    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

    reply
    0
  • 巴扎黑

    巴扎黑2017-04-17 13:35:09

    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.

    reply
    0
  • 黄舟

    黄舟2017-04-17 13:35:09

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

    reply
    0
  • Cancelreply