Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can an object know its own constness?

With decltype and std::is_const the constness of a variable can be externally detected. But is it also possible for an object to know its own constness? Usage should be like:

#include <type_traits>
#include <iostream>
#include <ios>

struct Test
{
    Test() {}

    bool print() const
    {
       // does not work as is explained in https://stackoverflow.com/q/9890218/819272
       return std::is_const<decltype(*this)>::value; // <--- what will work??
    }
};

int main()
{
    Test t;
    const Test s;

    // external constness test
    std::cout << std::boolalpha << std::is_const<decltype(t)>::value << "\n";
    std::cout << std::boolalpha << std::is_const<decltype(s)>::value << "\n";

    // internal constness test
    std::cout << std::boolalpha << t.print() << "\n";
    std::cout << std::boolalpha << s.print() << "\n"; // <--- false??
}

Output on LiveWorkSpace Is this somehow possible?

MOTIVATION: I want to be able to detect whether a const member function is invoked on a const object or is coming from a non-const object. The object could e.g. represent a cache and the member a view. If the cache was const, one could presumably use an optimized draw routine, whereas if the underlying data was non-const, the draw routine would need to do periodically check if the data was refreshed.

NOTE: the related question asks how to break the build for const objects, but I don't quite understand if the answer to that implies a definite NO for my question. If not, I want to capture the constness in a boolean for further usage.

EDIT: as was pointed out @DanielFrey, the constructor is not a good place to test for constness. What about a const member function?


UPDATE: Thanks everyone for correcting my initially ill-posed question and providing the various parts of the answer (constructors' ill-defined constness, rvaluedness of this, the contextual meaning of const, the -with hindsight- obvious overload trick that I had overlooked, and the const reference aliasing loophole lurking in the shadows). For me this question was Stackoverflow at its best. I decided to select @JonathanWakely's answer because it showed how to define Mutable and Immutable classes that strengthen the constness concept to achieve what I want in a foolproof way.

like image 311
TemplateRex Avatar asked Mar 07 '13 19:03

TemplateRex


People also ask

Can objects be constants?

An object of a class may be declared to be const , just like any other C++ variable. For example: const Date birthday(7, 3, 1969); declares a constant object of the Date class named birthday .

What is const& in c++?

The const keyword specifies that a variable's value is constant and tells the compiler to prevent the programmer from modifying it.


1 Answers

It's not possible for constructors (the original question) because of

12.1 Constructors [class.ctor]

4 A constructor shall not be virtual (10.3) or static (9.4). A constructor can be invoked for a const, volatile or const volatile object. A constructor shall not be declared const, volatile, or const volatile (9.3.2). const and volatile semantics (7.1.6.1) are not applied on an object under construction. They come into effect when the constructor for the most derived object (1.8) ends. A constructor shall not be declared with a ref-qualifier.

For member functions (the current question), you could simply provide both a const and a non-const overload, forward both to a (private) method that takes the constness as a boolean template parameter.

like image 105
Daniel Frey Avatar answered Oct 20 '22 19:10

Daniel Frey