Reputation: 64293
I would like to break the compilation if the object is declared const.
The following doesn't work :
#include <type_traits>
struct A {
A() : v(0)
{
static_assert( ! std::is_const<decltype(*this)>::value, "declared as const" );
}
int& AccessValue() const
{
return const_cast< int& >( v );
}
int v;
};
int main()
{
A a1; // ok, this compiles
const A a2; // no, this break the compilation
a1.AccessValue() = 5; // ok
a2.AccessValue() = 6; // OPS
}
So, is there a way to break the compilation if an object of this type is declared const?
Upvotes: 2
Views: 1997
Reputation: 300439
You are heading the wrong way.
The type of this
is purely dictacted by the signature of the method in which you use it. That is, this
is always of type cv T* const
where cv
corresponds to the CV qualifiers of the method.
Therefore, in a constructor, this
is just T* const
.
const_cast
is a code smell, normally only of use when dealing with const
-broken legacy libraries... or (sometimes) to avoid violating DRY. In new code, you should not have to use it.
You are left with a choice:
AccessValue
non-const, since it is noti
as being mutable
.I would advise choosing the former solution. Giving away a handle to a private
attribute is bad already (breaks encapsulation), no need to violate const
correctness as well.
Upvotes: 4
Reputation: 206919
For your specific example, making i
mutable would achieve your goal:
int& AccessValue() const
{
return v;
}
mutable int v;
This is from §7.1.6.1/4 [dcl.type.cv]:
Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.
Note that you can't modify v
using a pointer-to-member on a const object - §5.5/5 of n3290 draft [expr.mptr.oper]:
[ Note: it is not possible to use a pointer to member that refers to a mutable member to modify a const class object. For example,
struct S {
S() : i(0) { }
mutable int i;
};
void f()
{
const S cs;
int S::* pm = &S::i; // pm refers to mutable member S::i
cs.*pm = 88; // ill-formed: cs is a const object
}
— end note ]
Upvotes: 1
Reputation: 837
you can have multiple variables referring to the same object, some mutable and some const. For example:
A a1;
const A &a2 = a1;
A * const pa = &a1;
f(a1);
....
void f(const A &a);
should these be allowed in your case? Conversion from mutable to const is implicit the reverse is not. Maybe if you give an example will help.
EDIT: (in response to modified code) with a const object you can call only const member function. why not have:
int& AccessValue()
{
return v;
}
an the compiler with complain if you call AccessValue on a non const object.
Upvotes: 0