2

Consider the following class:

class ConstTest
{
public:
    ConstTest() : myPrivateData(42) {}

    const int* getMyPrivateData() const {std::cout << "const" << std::endl; return &myPrivateData;}
    int* getMyPrivateData() {std::cout << "non-const" << std::endl; return &myPrivateData;}

private:
    int myPrivateData;
};

is there any rule in which context which getter is used. My impression is that only in a const environemtn the const getter is called. Can anyone confirm this? I would very much appreciate an offical source because I would like to rely on that feature.

EDIT:

I am aware I can try it. But can I rely on it in terms of the standard?

  • 1
    Yes. That's it. – Deduplicator Aug 29 '18 at 12:05
  • 1
    Where could I have found that information, except for trying? –  Aug 29 '18 at 12:06
  • 1
    The rules are most likely defined in standard, but I don't know where exactly. – Yksisarvinen Aug 29 '18 at 12:07
  • try printing from the getter functions you can observe this. – AdityaG Aug 29 '18 at 12:07
  • 1
    @Pi We have a list of [recommended books](https://stackoverflow.com/q/388242/1171191). – BoBTFish Aug 29 '18 at 12:07
  • @Pi Well you can probably just pick one of the beginner ones, any of those should cover `const`-correctness. If you are a student, your college or university library probably has one of them. If you are already working but learning C++ as a new language, your employer should have some sort of library, ebook resource, or training budget. – BoBTFish Aug 29 '18 at 13:01

4 Answers4

2

I am aware I can try it. But can I rely on it in terms of the standard?

over.match.funcs/4+5:

  1. For non-static member functions, the type of the implicit object parameter is

    • “lvalue reference to cv X” for functions declared without a ref-qualifier or with the & ref-qualifier

    • “rvalue reference to cv X” for functions declared with the && ref-qualifier

      where X is the class of which the function is a member and cv is the cv-qualification on the member function declaration. [ Example: For a const member function of class X, the extra parameter is assumed to have type “reference to const X”. — end example ] For conversion functions, the function is considered to be a member of the class of the implied object argument for the purpose of defining the type of the implicit object parameter. For non-conversion functions introduced by a using-declaration into a derived class, the function is considered to be a member of the derived class for the purpose of defining the type of the implicit object parameter. For static member functions, the implicit object parameter is considered to match any object (since if the function is selected, the object is discarded). [ Note: No actual type is established for the implicit object parameter of a static member function, and no attempt will be made to determine a conversion sequence for that parameter ([over.match.best]). — end note ]

  2. During overload resolution, the implied object argument is indistinguishable from other arguments. The implicit object parameter, however, retains its identity since no user-defined conversions can be applied to achieve a type match with it.

Swordfish
  • 12,971
  • 3
  • 21
  • 43
1

That's correct. So if you have a code like this:

ConstTest a;
a.getMyPrivateData();

const ConstTest b;
b.getMyPrivateData();

It prints:

non-const
const

The same applies to other modifiers, like volatile. So your class could also have another method to handle the volatile case:

class ConstTest
{
public:
    ConstTest() : myPrivateData(42) {}

    const int* getMyPrivateData() const {std::cout << "const" << std::endl; return &myPrivateData;}
    int getMyPrivateData() volatile {std::cout << "volatile" << std::endl; return volatilePrivateData;}
    int* getMyPrivateData() {std::cout << "non-const" << std::endl; return &myPrivateData;}

private:
    int myPrivateData;
    volatile int volatilePrivateData;
};

And this code:

ConstTest a;
a.getMyPrivateData();

const ConstTest b;
b.getMyPrivateData();

volatile ConstTest c;
c.getMyPrivateData();

Prints:

non-const
const
volatile
HugoTeixeira
  • 4,674
  • 3
  • 22
  • 32
0

You can test it yourself:

#include <iostream>

class ConstTest
{
public:
    ConstTest() : myPrivateData(42) {}

    const int* getMyPrivateData() const {std::cout << "const" << std::endl; return &myPrivateData;}
    int* getMyPrivateData() {std::cout << "non-const" << std::endl; return &myPrivateData;}

private:
    int myPrivateData;
};

int main()
{
    auto a = ConstTest();
    const auto b = ConstTest();

    a.getMyPrivateData();
    b.getMyPrivateData();
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
0

A good indication that this is allowed by design is that the standard library uses it.

See for example std::vector::data

T* data() noexcept;
const T* data() const noexcept;
Caleth
  • 52,200
  • 2
  • 44
  • 75