Behavior when dereferencing the .end() of a vector of strings
You said:
I'm wondering if it's "safe" to set a string equal to whatever is returned by dereferencing the off-the-end iterator of a vector of strings
No, it is not safe. From http://en.cppreference.com/w/cpp/container/vector/end
Returns an iterator to the element following the last element of the container.
This element acts as a placeholder; attempting to access it results in undefined behavior.
Why is the end() element in Associative container print the same value as the last element?
You invoked undefined behavior, std::set::end
Returns an iterator to the element following the last element of the
set.
This element acts as a placeholder; attempting to access it results in
undefined behavior.
Undefined behavior renders the entire program meaningless.
Attempt to dereference a past-the-end iterator' when sorting a vector of filesystem paths
std::sort
requires a strict weak ordering comparator, as described in [alg.sorting]/p3:
[...] For algorithms other than those described in [alg.binary.search],
comp
shall induce a strict weak ordering on the values.
A strict weak ordering comparator should return true
only if the left hand side operand precedes the right hand side operand, and false
otherwise.
The std::basic_string::compare
function encodes its result as <0
, 0
and >0
, if the string is lexicographically less, equal or greater than the argument expression, respectively. This allows to determine the mutual relation between its arguments in a single pass. However, both positive and negative values are implicitly convertible to the true
boolean value, and so the result will be misinterpreted by any standard library algorithm, leading to undefined behavior. In order to avoid that, the std::sort
function call could look as follows:
std::sort(files.begin(), files.end(), [](const auto& lhs, const auto& rhs) {
if (fs::is_directory(lhs) && !fs::is_directory(rhs)) {
return true;
} else if (fs::is_directory(rhs) && !fs::is_directory(lhs)) {
return false;
} else {
return lhs.filename().string() < rhs.filename().string();
// ~^~
}
});
std::transform behavior when iterating past container.end()
Yes, it's undefined behavior. It's your responsibility to avoid running past the end of the vector, not the compiler's.
What do you mean by, "b.end()
is not overwritten"? If you mean that you expected the vector to change length, then no, it didn't, you can't change a vector's length this way.
Related Topics
Constant Expression Initializer for Static Class Member of Type Double
How to Create a Shared Library with Cmake
Difference Between Rdtscp, Rdtsc:Memory and Cpuid/Rdtsc
Programmatically Reading a Web Page
How to Dynamically Allocate a Matrix
Changing Function Access Mode in Derived Class
Function Prologue and Epilogue in C
Can Someone Please Explain the "Indices Trick"
Pthreads: Thread Starvation Caused by Quick Re-Locking
Use Channel Hiearchy of Boost.Log for Severity and Sink Filtering
How to Set Timeout for Std::Cin
Insert VS Emplace VS Operator[] in C++ Map
Pointer-To-Pointer Dynamic Two-Dimensional Array
Inheritance or Composition: Rely on "Is-A" and "Has-A"