Skip to content

Instantly share code, notes, and snippets.

@quantumelixir
Created November 26, 2017 17:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save quantumelixir/3162c9f7f1c77a429871ffeabdd65763 to your computer and use it in GitHub Desktop.
Save quantumelixir/3162c9f7f1c77a429871ffeabdd65763 to your computer and use it in GitHub Desktop.
Lifetime of C++ Temporaries
// A little exercise to demonstrate the lifetime of temporaries in
// C++. Inspired by the comment in this video
// https://youtu.be/xu7q8dGvuwk?t=3156 at CppCon2017 by Titus Winters.
//
// Two things to note:
//
// - Temporaries (rvalues) can have their lifetimes extended by
// binding them to a const reference. But the lifetime is extended
// only to the lifetime of the const reference itself, no more (see
// the Split(..) function below).
//
// - References to temporaries that have been destructed can cause
// undefined behavior upon using them to make illegal memory
// accesses (see the commented out code in the main function).
#include <iostream>
#include <vector>
#include <string>
// a string view
using string_view = std::pair<const char*, const char*>;
std::ostream& operator<<(std::ostream& output, const string_view s) {
output << std::string(s.first, s.second - s.first);
return output;
}
// a joiner
template<typename T>
std::string Join(T v) {
return std::string(v);
}
template<typename T, typename... Trest>
std::string Join(T first, Trest... rest) {
return first + Join(rest...);
}
// a splitter that returns references into the input string
std::vector<string_view> Split(const std::string& s,
const std::string& delimiter) {
std::vector<string_view> result;
const char *beg = s.c_str(), *end = s.c_str() + s.size();
const char* cur = beg;
auto loc = s.find(delimiter);
const char* nxt = (loc == std::string::npos) ? end : beg + loc;
while (cur < end) {
result.push_back(std::make_pair(cur, nxt));
cur = nxt + delimiter.size();
auto loc = s.find(delimiter, cur - beg);
nxt = (loc == std::string::npos) ? end : beg + loc;
}
return result;
}
int main() {
{
auto intermediate = Join("fun", " ", "little", " ", "experiment!",
"fun", " ", "little", " ", "experiment!",
"fun", " ", "little", " ", "experiment!");
auto result = Split(intermediate, " ");
for (const string_view elements : result) {
std::cout << elements << std::endl;
}
}
// this causes undefined behavior!
// {
// auto result = Split(Join("fun", " ", "little", " ", "experiment!",
// "fun", " ", "little", " ", "experiment!",
// "fun", " ", "little", " ", "experiment!"), " ");
// for (const string_view elements : result) {
// std::cout << elements << std::endl;
// }
// }
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment