1
votes

I know that a const object can't call a non-const member function. It says so in the C++14 Standard (ISO/IEC 14882:2014) Section 9.3.2, Paragraph 3:

A cv-qualified member function can be called on an object-expression (5.2.5) only if the object-expression is as cv-qualified or less-cv-qualified than the member function.

Does this constraint make sense if the member function does not modify anything? Or if the member function modifies a mutable variable? For example:

class My_Class {
    public:
        mutable int value;
        void function( int x ) const { value = x; } //     Correct
      //void function( int x )       { value = x; } // Not Correct
        My_Class() : value(0) {}
};

int main(){

    const My_Class obj;
    obj.function( 1 );

    return 0;
}

In this specific case, if the function is const, the program is correct and the function can modify a variable of the const object. If the function is not const, the program is not correct. So in the end, I need to write const to be able to modify something, which should be the opposite purpose of const.

Does anyone know why this rule is designed this way?

3
const objects are not meant to be changed. That's that. mutable is just a cheat and is meant to be used on member variables which aren't really part of the internal state of the object (e.g. a mutex, which must be locked or unlocked regardless of const).DeiDei
re. "If the function is not const, the program is not correct"... const is used to indicate conceptual sameness not byte sameness. non-const functions are not expected to have to change something.london-deveoper

3 Answers

2
votes

Does [Section 9.3.2, Paragraph 3 of] make sense if the member function does not modify anything? Or if the member function modifies a mutable variable?

Yes, it does. The caller of the function cannot in general know whether the function modifies any non mutable member. It knows whether the function is const or not, so the compiler can only make a decision based on that.

A non const function could modify the non mutable state, so you obviously may not call it on a const object. Whether the non const function does modify the state is irrelevant since it is an implementation detail that is not available when deciding if the call is allowed. In other words, constness is part of the interface of the function, while the implementation of the function is not part of the interface. The interface of the function is fully specified by its declaration.

An example:

struct C {
    mutable int a;
            int b;
    void do_something();
};

const C c;
c.do_something();

Does it make sense to allow the call do_something? Does the fact that do_something might not modify b affect that? How could we assume that do_something does not modify b?

The answers are: It wouldn't make sense. It does not have an effect. There is no way we could make such assumption.

Writing a non const member function that doesn't modify any non mutable state - at least potentially or allow such modification indirectly by returning a non const reference / pointer to this - makes little sense, although the standard does permit doing so.

So in the end, I need to write const to be able to modify something, which should be the opposite purpose of const.

That might seem oxymoronic, but that is because it is an oversimplification. You need to write const to be able to modify the mutable state of a const object. The const that you write declares that you do not modify any non mutable state, and that declaration gives the permission to call it on const objects.

Your commented-out non-const function is still correct to use with non-const objects.

2
votes

There is a fundamental misunderstanding in your question:

class My_Class {
    public:
        mutable int value;
        void function( int x )       { value = x; } // Absolutely fine
        My_Class() : value(0) {}
};

mutable does not mean "can only be modified in a const member function". It means "can be modified even in a const member function".

1
votes

The mutable keyword,

Applies to non-static class members of non-reference non-const type and specifies that the member does not affect the externally visible state of the class (as often used for mutexes, memo caches, lazy evaluation, and access instrumentation). mutable members of const class instances are modifiable

You're questioning the validity of a C++ keyword. I feel the examples in this definition, provide positive proof that such a keyword is needed, and that mutable as imagined by the designers of the language is a boon to us.