Я придумал следующие реализации, которые охватывают пустой сценарий ввода без вызова какого-либо неопределенного поведения.
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
std::vector<std::string> contents = {"'cause", "'til", "holdin'", "don't", ""};
void impl1() {
for(auto & content:contents){
if(!content.empty() && (*content.begin()) == '\''){
content.erase(content.begin());
}
if(!content.empty() && content.back() == '\''){
content.pop_back();
}
std::cout << content << " " << std::endl;
}
}
void impl2(){
auto erase_if = [](auto& container, auto&& itr, auto val){
if(!(itr == std::end(container)) && ((*itr) == val)){
container.erase(itr);
}
};
for(auto & content: contents){
erase_if(content, content.begin(), '\'');
erase_if(content, std::string::iterator{&content.back()}, '\'');
// print trimmed output
std::cout << content << " " << std::endl;
}
}
int main(void){
//impl1();
impl2();
return 0;
}