Can I initialize a constant integer with a L-value?

Viewed 100

I've got a question in my assignment that asks me to evaluate whether the following function call is correct. I'm not sure if a const int can be initialized with a variable of type const int&. I know that a const int can be initialized with another int, for example

int i=3; const int j=i 

works perfectly fine, but I'm not sure if the following code is semantically correct (the line const int j=bar(++i);)

int foo (int& i) {return i+=2;}

const int& bar(int &i){ return i+=2;}

int main(){
   int i=5;
   const int j=bar(++i);
}
2 Answers

Yes it can. You can initialize an object with any value category.

When constructing the type, it will simply call its constructor with the correct overload, such as type(type&& other) or type(type const&).

For trivial types, it's always a copy. So as long as the types are compatible, no matter their value category, it will work.

Initializing a reference is different. You must have an expression with a compatible value category. For example, creating a mutable reference from your function won't work:

int& j = bar(++i); // won't compile, int& cannot be bound to int const&

This is because bar returns a reference to const, thus cannot be bound to a reference to mutable.


As a side note, even though it's an int constant, it is not a compile time constant anymore. Thus you won't be able to use it as an array size or template parameter.

To fix that you'd have to use constexpr, which will guarantee that the value of your variable is available at compile time.

int a = 9;
constexpr int b = a; // Won't work, `a` is a runtime value, `b` is compile time

constexpr int a = 1;
constexpr int b = a + 1; // Works! Both compile time values

A reference is basically just an alias to the object it is bound to (with possible indication of immutability by const). Since bar(++i) returns a reference bound to i, it is the same as if you initialized j by i after bar(++i) call:

bar(++i);
const int j = i;

Const reference just says that you cannot modify the bound object through that reference. But there is nothing in your code that would try doing this.

Related