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.
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 .
The const keyword specifies that a variable's value is constant and tells the compiler to prevent the programmer from modifying it.
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) orstatic
(9.4). A constructor can be invoked for aconst
,volatile
orconst volatile
object. A constructor shall not be declaredconst
,volatile
, orconst volatile
(9.3.2).const
andvolatile
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With