I have the following code:
class c_int {
public:
int &i;
c_int(int &in) : i(in) {
};
c_int(const int &in) : i(in) {
};
};
int main (void) {
const int i = 10;
const c_int c(i);
std::cout << c.i << std::endl;
return 0;
}
Compiling it gives the following error message:
tmp.cpp:12:30: error: invalid initialization of reference of type 'int&' from ex
presion of type 'const int'
I am having a bit of trouble, figuring out how to get this to work, how should I initialize a reference inside a const object?
Edit: Ideally I would like this object to serve for non-const ints too; when the object is not declared const.
Further Edit:
I wish to use the object like this also:
int main (void) {
int i = 10;
c_int c(i); // for some reason this calls the 2nd of my constructors, does name mangling not take const into account?
c.i = 9;
std::cout << i << std::endl;
return 0;
}
The problem is not that your object is const : it is that you are trying to bind a const reference to a non-const one : this is illegal.
You can bind a const reference to a const member :
class c_int {
public:
const int &j;
c_int(const int &in) : j(in){ };
};
int main (void) {
const int i = 10;
c_int c(i);
std::cout << c.j << std::endl;
}
You can still uses two different classes for const and non const objects, or if you really need a single class and know what you are doing, use a const_cast (really discouraged : any attempt to modify the object will be undefined behavior) :
class c_int {
public:
int& i;
c_int(int& in) : i(in){ }
c_int(const int& in) : i(const_cast<int&>(in)){ } // Very wrong
};
Or, forget about passing by reference and use value semantics :
class c_int {
public:
int i;
c_int(int in) : i(in){ }
};
Edit:
You can still add a constructor taking a non-const reference for cases where your int argument is not const :
class c_int {
public:
const int &j;
c_int(const int &in) : j(in){ };
c_int(int &in) : j(in){ }
};
int main (void) {
const int i = 10;
const c_int c(i);
std::cout << c.j << '\n';
int i2 = 11;
const c_int d(i2);
std::cout << d.j << '\n';
}
Live demo.
I would suggest you have two different classes. One which holds a const reference, and one which holds a non-const reference. This is similar to the way standard containers have both iterator and const_iterator as two seperate classes.
class c_int {
public:
int &i;
c_int(int &in) : i(in) {};
};
class const_c_int {
public:
int const &i;
c_int(int const &in) : i(in) {};
};
If you want to avoid repeating code, you could make a template:
template<typename T>
class c_generic {
public:
T& i;
c_generic(T& in) :i(in) {}
};
typedef c_generic<int> c_int;
typedef c_generic<int const> const_c_int;
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