decltype(&e)
gives you exactly the type of the expression &e
with the value category translated to the matching reference-qualification.
So the cast const_cast<decltype(&e)>(&e)
doesn't do anything. It casts &e
which has type int* const*
and value category prvalue to type int* const*
, i.e. const_cast<decltype(&e)>(&e)
is an expression that itself has type int* const*
and value category prvalue and the result has the same value as &e
.
If you want to remove the const
, you want a cast to int**
, not int* const*
. You need to remove the const
from the type, e.g. with std::remove_cvref_t
you can remove reference and const
qualification from e
's declared type (which is what decltype(e)
will return):
*temp = const_cast<std::remove_cvref_t<decltype(e)>*>(&e);
However, this is dangerous. Someone might change *arr
to be an object that is non-modifiable and then the compiler won't give you any warning or error anymore, because the const_cast
suppresses it. Then you'll have undefined behavior.
If you need the reference to be const most of the time, it is better to start with a non-const
reference and then add a const
one for the scope where it should be const
:
for (auto& e_modifiable : *arr) {
{
const auto& e = e_modifiable;
// some code that uses e...
}
// *temp was probably unintended. It has the wrong type and
// temp is uninitialized. However `**temp = 22;` also is UB
// because all elements of the array are null pointers.
temp = &e_modifiable; // error
}
Also note other comments about your code under your question which are valid. All in all I suspect that you are using way too many pointers and new
for what you are trying to do, although there isn't enough context to know what exactly that is.