0

What is the difference between this three functions regarding using "const" qualifier

int& func (const int& var)

I know that the const qualifier keep input read-only and can not be changed inside the function.

int const func (int& var)

and this one also return const variable, but what does it mean? it means it can not be changed through the code?

int& func (int& var) const

and what about this one? I have no idea what this means.

  • 1
    The first two don't make sense, since a reference cannot have top-level `const`. – Ben Voigt Jan 05 '19 at 04:20
  • @Ben what does "top-level const" mean? and what if we declare the function and pass copy argument instead of a reference? –  Jan 05 '19 at 04:23
  • None of these are valid C++ at all. (Except the third one, if it appears inside a class definition.) – aschepler Jan 05 '19 at 04:24
  • @MehdiBabaMehdi: Top-level const means that the thing itself (whether that thing is a parameter or a variable or a return value) is const, not what it points to. But with references, the only useful const is on what the reference points to, like `const int &`. A reference can't be marked `const`, because there are no mutating operations on references to begin with. – Ben Voigt Jan 05 '19 at 04:29
  • Sorry for the first declaration, I made a mistake in the place of const. it should be before int&. I modified it. –  Jan 05 '19 at 04:38
  • Possible duplicate of [Meaning of 'const' last in a function declaration of a class?](https://stackoverflow.com/questions/751681/meaning-of-const-last-in-a-function-declaration-of-a-class) – Dev Null Jan 05 '19 at 04:49

2 Answers2

3
int& func (const int& var)
           ^^^^^^^^^^^^^^

The highlighted part is an argument declaration. The part const int& is the type of the argument variable and var is the name of the variable.

Normally, constness applies to the left, but in this case, it is the left most token of the type. In this exceptional case, it applies to the right instead. To the right is int. Therefore it is a const int. As a whole, the type of the argument is reference to const int.

int const func (int& var)
^^^^^^^^^

The highlighted part is the return type declaration of the function. The return type is a const int object. Although it is well-formed, it never really makes sense to return a const int since the constness is irrelevant to the caller. Most compilers have options to warn in case of such declaration.

Technically, returning a const class object may be different from returning a non-const one, but I have not seen a case where that would be useful.

int& func (int& var) const

Const after the argument list applies to the function itself. A const member function may not be called on a non-const object or reference. The implicit *this argument of the member function will be const. Const qualifier cannot be applied on a non-member function or a static member function.


Regarding old version of the question...

What is the difference between this three functions regarding using "const" modifier

int& func (int& const var)
int& const func (int& var)

These two are ill-formed. Const qualifier cannot apply to a reference (although, you can have a reference to a const type, and such references are colloquially called const references).

Community
  • 1
  • 1
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • In the first declaration, I made a mistake in the place of const. it should be before int&. I modified it. –  Jan 05 '19 at 04:40
  • @MehdiBabaMehdi I've updated the answer regarding the new version. – eerorika Jan 05 '19 at 04:58
0

You need to read the const quantifiers from right to left to understand them. so for example int const func(int& var) returns a const int

Here is an example of the use:

#include <stdexcept>
#include <iostream>

int& func(const int& var)
{
    std::cout << "func(const int& var) called\n";
    throw std::runtime_error("not implemented");
}

int const func(int& var)
{
    std::cout << "func(int& var) called\n";
    throw std::runtime_error("not implemented");
}

struct A {
    int& func(int& var) const
    {
        // i = 2; illigal since const function
        std::cout << "func(int& var) const called\n";       
        throw std::runtime_error("not implemented");
    }
    int i;
};

int main()
{
    try
    {
        const int i = 1;
        func(i);
    }
    catch (std::exception) {}

    try
    {
        int j = 2;
        func(j);
    }
    catch (std::exception) {}

    try
    {
        A a;
        int k = 2;
        a.func(k);
    }
    catch (std::exception) {}

}
Damian
  • 4,395
  • 4
  • 39
  • 67