Here's a snippet from my C++ code:
std::queue<std::string> get_file_names(const std::string &indir)
{
std::queue<std::string> file_names;
fs::recursive_directory_iterator end;
for (fs::recursive_directory_iterator it(indir); it != end; it++) {
const std::string &extn = it->path().extension().string();
if (extn == ".zip") {
const std::string &file_name = it->path().string();
file_names.push(file_name);
}
}
return file_names;
}
Is it a good practice to make every string you won't modify a const reference? I have trouble understanding how can such a reference exist in this context at all. Like the return value of it->path().string()
above. How can it be assigned to a reference that can be later used outside of the scope of the function when pushed back to a vector?
I feel like it has to do something with std::move
.
If you say that a function's return value is const: const int g(); you are promising that the original variable (inside the function frame) will not be modified. And again, because you're returning it by value, it's copied so the original value could never be modified via the return value.
- const references allow you to specify that the data referred to won't be changed. A const reference is actually a reference to const. A reference is inherently const, so when we say const reference, it is not a reference that can not be changed, rather it's a reference to const.
The const member functions are the functions which are declared as constant in the program. The object called by these functions cannot be modified. It is recommended to use const keyword so that accidental changes to object are avoided. A const member function can be called by any type of object.
Then, no, you can't do that; in a const method you have a const this pointer (in your case it would be a const Foo * ), which means that any reference you can get to its fields1 will be a const reference, since you're accessing them through a " const path".
If you say that a function’s return value is const: you are promising that the original variable (inside the function frame) will not be modified. And again, because you’re returning it by value, it’s copied so the original value could never be modified via the return value.
When function returns a reference it means it returns a implicit pointer. Return by reference is very different from Call by reference. Functions behaves a very important role when variable or pointers are returned as reference.
In the last episodes, we covered the first three topics, const functions and const local variables, then const member variables and today we are covering return types. What kind of variables can a function return? It can return values, references and pointers. And all of these can be const. Let’s have a look at each of them.
Return const pointers Pointers are similar to references in a sense that the pointed object must be alive at least as long as the caller wants to use it. You can return the address of a member variable if you know that the object will not get destroyed as long as the caller wants the returned address.
Your code:
const std::string &file_name = it->path().string();
extends the lifetime of the temporary std::string
returned by std::filesystem::path::string()
. Since you've marked that as const
, it can't be moved into file_names
, it must be copied. Assuming you want a move, you would write:
auto&& file_name = // ...
file_names.push(std::move(file_name));
Notice that std::queue
has a push()
overload for r-value references.
Modern C++ provides a lot of opportunities for compilers to optimize, so avoiding questions/"confusion" about dangling references (the auto&&
syntax is "new" in C++11) might be a better approach:
auto file_name = // ...
file_names.push(std::move(file_name));
Writing "natural" code that "looks and behaves like the int
s" is often a good approach. In the unlikely situation you find that this is really a performance bottleneck, you can revisit; write your code for clarity first.
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