CS106L Lecture 3: C++11 List Initialization and Lvalues vs Rvalues

Hello everyone, today we will look at Lecture 3 of CS106L Spring 2025, which mainly introduces initialization, references, lvalues and rvalues, as well as the const qualifier.

CS106L Lecture 3: C++11 List Initialization and Lvalues vs Rvalues

Starting with a Bug

Today I took on a development requirement to set the directory path in a static member function of a class in a configurable way. So I changed the originally hardcoded directory path to a member variable and assigned the directory path in the constructor. Just as I was about to compile, clangd warned me that I cannot call a regular member variable in a class member function, so I added static to the member variable as well.

static std::string path{ "/home/zhangsan/" };

When I ran the compilation script, the compiler indicated that it could not find <span>non-const static data member must be initialized out of line</span>, meaning it needs to be initialized in the cpp file.

I thought, it’s 2025, C++ can’t still be this primitive, right? Then AI told me that after C++17, I can add inline at the declaration to solve this problem.

In this bug, I did not fully understand static and did not pay attention to the issues that the initialization list introduced in C++11 might bring, which forced me to relearn about initialization lists.

C++11 Initialization Lists

First, let’s look at how C++ assigned values before initialization lists.

CS106L Lecture 3: C++11 List Initialization and Lvalues vs RvaluesOf course, it was direct assignment; floating-point numbers could be assigned to integers, and int could also be directly assigned to char types.

This method, while straightforward, can lead to what is called narrowing conversion, which simply means loss of precision and a reduced data representation range.

With initialization lists, we can prevent narrowing conversion and get a compilation error directly. This allows for safer assignments and can be used across various data types.

CS106L Lecture 3: C++11 List Initialization and Lvalues vs Rvalues

For example, with vector, map, custom classes, etc., you might have forgotten that map can also insert data this way.

CS106L Lecture 3: C++11 List Initialization and Lvalues vs Rvalues

Lvalues and Rvalues

These two concepts can often be intimidating during interviews. They usually set the stage for rvalue references, move semantics, and perfect forwarding. If the earlier answers are not good, it may create pitfalls for the subsequent answers.

CS106L Lecture 3: C++11 List Initialization and Lvalues vs Rvalues

The left side of the equals sign is an lvalue, and the right side is an rvalue. ❌

This statement is incorrect.

To distinguish between lvalues and rvalues, refer to the image above. The key point to remember is that rvalues are temporary, about to be destroyed; any parameters or variables that can be used multiple times are definitely not rvalues.

const and References

A reference is essentially an alias for a variable; in C, it is like passing a pointer, allowing modifications within the function to affect the variable outside the function.

As for constants, they are read-only and cannot be written to.

CS106L Lecture 3: C++11 List Initialization and Lvalues vs RvaluesHere is a common mistake: using a const vector with a non-const reference. Although this error will be caught by the compiler, it is important to realize that variables with const restrictions must maintain that const status throughout the function’s parameter passing, unless explicitly using const_cast<> to remove the const restriction.

CS106L Lecture 3: C++11 List Initialization and Lvalues vs Rvalues

Leave a Comment