Can I remove constant from non-pointer variables

L

lovecreatesbeauty

Hello experts,

Is const_cast only applied to pointers or references? If I have a
constant object, then how can I remove constant attribute from it?


#include <vector>
#include <string>
using namespace std;

class Type{
};

int main(int argc, char * argv[]){

const Type * cptr = 0;
Type * ptr = const_cast<Type *>(cptr); // #1 ok

const Type ct = Type();
Type t = const_cast<Type>(ct); // #2 error

const vector<Type> cv;
vector<Type> v = const_cast<vector<Type> >(cv); // 3# error
}




And suppose I have a function as follows, how can I remove the constant
from the parameter with type of
const vector<string>& sequence, or
const vector<string> sequence?

Could you please give me more suggestions on the declaration of this
function (or even all my code, thanks). Is it better for me to change
its declaration to some other formats? For example, may I declare it
one of the following:

vector<string> & rearrange(vector<string>& sequence);
vector<string> rearrange(vector<string> sequence);
vector<string> & rearrange(const vector<string>& sequence);
vector<string> rearrange(const vector<string> sequence);



vector<string> rearrange(const vector<string>& sequence){
vector<string> vecTmp = sequence;

// vector<string> vecTmp =
// const_cast<vector<string> >(sequence); // #4 error


int iSeqWth = vecTmp.size();
string strSwp;

for (int i = 0; i < iSeqWth; ++i){
for (int j = i + 1; j < iSeqWth; ++j){
if (atoi(vecTmp.c_str()) > atoi(vecTmp[j].c_str())){
strSwp = vecTmp;
vecTmp = vecTmp[j];
vecTmp[j] = strSwp;
}
}
}

return vecTmp;
}

-- lovecreatesbeauty
 
J

joe.els

Hi

You really shouldn't try to "remove the constant".
Things are declared constant, because they shouldn't be modified.

The const_cast operator cannot be used to directly override a
variable's constant status. Yes, it only works with pointers.

It should also be noted, that using the resulting pointer (from the
const_cast operator) to perform write operations might result in
undefined behavior.

About your rearrange/sorting function:
Parameters can be passed by reference or by value.
A parameter passed by reference, gives you a reference to the original
value and changing the parameter would result in changing the original
value.
A parameter passed by value, gives you a copy of the original and
changes on the parameter wouldn't effect the original (given that the
copy constructor and assignment operator where implemented correctly).

If you intend to sort the original vector, declare the function as
void rearrange(vector<string>& p_vec)
{
// sorting login in here
// no return statement needed
}
Should you intend to sort a copy of the original vector, you could
declare the function as:
vector<string> rearrange(vector<string> p_vec)
{
// sorting login in here
return p_vec;
}

Alternatively on can do what you've already done
vector<string> rearrange(const vector<string> p_vec)
{
// create a copy of p_vec
// sort the copy
// return the copy
}

Joe
 
L

lovecreatesbeauty

Thanks. But there is a conversion from const to non-const in my code
without the C++ standard compliant explicit conversion. It is:

vector<string> rearrange(const vector<string>& sequence){
vector<string> vecTmp = sequence; //
non-standard conversion! so I want to enforce the standard explicit

// conversion on it as following, but failed.

// vector<string> vecTmp =
// const_cast<vector<string> >(sequence); // #4 error.

// ...

}
 
I

Ian

lovecreatesbeauty said:
Hello experts,

Is const_cast only applied to pointers or references? If I have a
constant object, then how can I remove constant attribute from it?
Why on earth would you want to?

const is there for a reason!

Ian
 
I

Ian

lovecreatesbeauty said:
Thanks. But there is a conversion from const to non-const in my code
without the C++ standard compliant explicit conversion. It is:

vector<string> rearrange(const vector<string>& sequence){
vector<string> vecTmp = sequence; //
non-standard conversion! so I want to enforce the standard explicit

// conversion on it as following, but failed.

// vector<string> vecTmp =
// const_cast<vector<string> >(sequence); // #4 error.

// ...

}
why not

vector<string> vecTmp( sequence.begin(), sequence.end() );

Ian
 
U

upashu2

const means you can't change me., it doesn't mean you can't read me. No
conversion is taking place here. You are simply copying the
value/contents of a const object into a non-const object. which is
absolutely right.

To copy the value from a const object, we don't need const_cast<>
..Instead purpose of const_cast is to modify the object contents by
removing the const qualifier temprorily.
const Type * cptr = 0;
Type * ptr = const_cast<Type *>(cptr);
Here you are removing const qualifier using const_cast<>, so that your
const Type * is now Type *, and ptr is just pointing to your original
object which value you can modify through ptr.

class Type{
public: int i;
Type(int j):i(j){}
};
int main(int argc, char * argv[]){

const Type * cptr = new Type(20);
cout<<cptr->i<<endl;;
const_cast<Type *>(cptr)->i=10; <<<<<<<<<
cout<<cptr->i<<endl;
}
Remember:
1. a write operation through the resulting pointer, reference, or
pointer to data member might produce undefined behavior.
2. You cannot use the const_cast operator to directly override a
constant variable's constant status.
 
S

Srini

Along with the reasonings given above, const_cast is mainly used during
parameter passing to, say, legacy routines. Legacy code might not take
const references or pointers. In such cases, user code today, might
need to use const_cast on the parameters. If a function is taking an
object and not a reference or a pointer as its argument, what the
function would get is anyway a copy of the object. Changes to the
object made in the function would not be reflected in the caller's
object.

// some function
voif fun(Type obj)
{
// ...
}

// user code
const Type obj;
fun(obj);

Here, obj is being passed by value and const_cast is not required
anyway. Its known that const_cast cannot be applied on objects
themselves. I am trying to convey that most of the times its
unnecessary and does not make sense to use const_cast on objects.

Srini
 
G

Greg

lovecreatesbeauty said:
Hello experts,

Is const_cast only applied to pointers or references? If I have a
constant object, then how can I remove constant attribute from it?


#include <vector>
#include <string>
using namespace std;

class Type{
};

int main(int argc, char * argv[]){

const Type * cptr = 0;
Type * ptr = const_cast<Type *>(cptr); // #1 ok

const Type ct = Type();
Type t = const_cast<Type>(ct); // #2 error

const vector<Type> cv;
vector<Type> v = const_cast<vector<Type> >(cv); // 3# error
}




And suppose I have a function as follows, how can I remove the constant
from the parameter with type of
const vector<string>& sequence, or
const vector<string> sequence?

Could you please give me more suggestions on the declaration of this
function (or even all my code, thanks). Is it better for me to change
its declaration to some other formats? For example, may I declare it
one of the following:

vector<string> & rearrange(vector<string>& sequence);
vector<string> rearrange(vector<string> sequence);
vector<string> & rearrange(const vector<string>& sequence);
vector<string> rearrange(const vector<string> sequence);



vector<string> rearrange(const vector<string>& sequence){
vector<string> vecTmp = sequence;

// vector<string> vecTmp =
// const_cast<vector<string> >(sequence); // #4 error


int iSeqWth = vecTmp.size();
string strSwp;

for (int i = 0; i < iSeqWth; ++i){
for (int j = i + 1; j < iSeqWth; ++j){
if (atoi(vecTmp.c_str()) > atoi(vecTmp[j].c_str())){
strSwp = vecTmp;
vecTmp = vecTmp[j];
vecTmp[j] = strSwp;
}
}
}

return vecTmp;
}

-- lovecreatesbeauty


Actually, removing the const from a declaration is not all that
difficult. Though even experts have been tripped up from time to time.
Here, i will demonstrate the proper procedure.

Before:

const vector<string> sequence;

After:

vector<string> sequence;

The const portion of the declaration has been successfully removed; now
the sequence variable can be used in a non-const manner.

Next week, I will be demonstrating a similar procedure for "volatile"
declarations which you won't want to miss.

Greg

ps. in all seriousness, there is no other way to "remove" a constness
from a declaration. Either the variable is declared const or it is not
(or course if non-const it can still be made available to a function
only in a const form).
 
A

annamalai.gurusami

lovecreatesbeauty said:
vector<string> rearrange(const vector<string> sequence);

I think such a parameter declaration adds no value. What
is the point in making it const in the above case?
Anybody?

void g(const T& t);
void g(T& t);
void g(T t);
void g(const T t); // const adds no value

Rgds,
anna
 
A

annamalai.gurusami

It should also be noted, that using the resulting pointer (from the
const_cast operator) to perform write operations might result in
undefined behavior.

*might* means?

Rgds,
anna
 
R

Richard Herring

*might* means?

If the object to which it points was originally declared const, on some
platforms the compiler might for instance allocate it in read-only
memory.

const T thing; // not legally modifiable
T * p = const_cast<T*>(&thing);
p->Modify(); // UB

If you're merely casting away a const that was added by an earlier cast,
there's no problem:

T thing; // modifiable
const T * p = &thing; // not modifiable via this pointer
T * q = const_cast<T*>(p); // cast away the const added by p
q->Modify(); // no problem, the original thing was non-const.
 
J

Jim Langston

lovecreatesbeauty said:
Hello experts,

Is const_cast only applied to pointers or references? If I have a
constant object, then how can I remove constant attribute from it?


#include <vector>
#include <string>
using namespace std;

class Type{
};

int main(int argc, char * argv[]){

const Type * cptr = 0;
Type * ptr = const_cast<Type *>(cptr); // #1 ok

Umm..what's wrong with:
Type * ptr = cptr;
const Type ct = Type();
Type t = const_cast<Type>(ct); // #2 error

Type t = ct;
const vector<Type> cv;
vector<Type> v = const_cast<vector<Type> >(cv); // 3# error

vector said:

I think you're getting a little confused as to what that const keyword is
actually doing. The const keywords means you can't change THAT variable.
Not that you can't READ from it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top