My brain sucks. It can remember the lyrics to songs or the power draw of a electronic component, but I keep forgetting those simple, useful helper functions you sometimes need. This sends me off Google again, searching through excellent sites like StackOverflow etc. Time to make a list…
Remove characters from a string:
#include <algorithm>
#include <iterator>
std::string input;
std::string result;
std::remove_copy(input.begin(), input.end(), std::back_inserter(result), 'a');
Replace characters in a string:
std::string input;
std::replace(input.begin(), input.end(), 'a', 'b');
Convert integer to std::string without the << operator:
std::to_string((long long)number);
Create a shared_ptr managing an array:
C++ < 17 -> std::shared_ptr<unsigned char> data = std::shared_ptr(new unsigned char[size], [](unsigned char *p) { delete[] p; });
C++ >= 17 -> std::shared_ptr<unsigned char[]> data = std::shared_ptr(new unsigned char[size]);
(In C++ < 17 you must use a custom deleter, because by default delete is called, not delete[]. Here a lambda function is passed to the shared_ptr constructor)
Advance an iterator by a number:
std::vector<SOME_TYPE> list;
std::vector::const_iterator iter = list.cbegin();
std::advance(iter, 5);
Append std::vector elements from one vector to another:
std::vector<SOME_TYPE> destination;
std::vector<SOME_TYPE> source;
destination.insert(destination.end(), source.cbegin(), source.cend());
(Why there is no push_back() overload for this is beyond me…)
Append std::vector elements from one vector to another (without duplicates):
std::vector<SOME_TYPE> destination;
std::vector<SOME_TYPE> source;
std::copy_if(source.cbegin(), source.cend(), std::back_inserter(destination), [&](const int & element) { return std::find(destination.cbegin(), destination.cend(), element) == destination.cend(); });
Conditionally erase elements from a vector:
std::vector<SOME_TYPE> src;
src.erase(std::remove_if(src.begin(), src.end(), [](auto & entry){ return <ERASE_CONDITION>;}), src.end());
For loops with iterator and auto:
std::vector<SOME_TYPE> foo;
for (auto fooIt = foo.cbegin(); fooIt != foo.cend(); ++fooIt) {
//...
}
Use this when you need an iterator.
For each with auto:
std::vector<SOME_TYPE> foo;
for (const auto & oneOfFoo : foo) {
//...
}
Make sure oneOfFoo is the type you want. Be careful when using auto-pointers etc.
Automatic loop counter type deduction (IdeOne):
std::vector<SOME_TYPE> foo;
for (decltype(foo)::size_type i = 0; i < v.size(); i++) {
//...
}
Here, i automatically has the type same type as std::vector<SOMETYPE>::size_type. Useful if you need to use an index for looping.
Output all content of a std::vector to a stream:
std::vector<std::string> words; //contains some strings
std::stringstream ss;
std::copy(words.begin(), words.end(), std::ostream_iterator(ss));
Bind a class member function to a std::function object:
class Foo {
void doSomething() {}
void doWithParameter(int p)
}
Foo foo;
std::bind(&Foo::doSomething, foo);
std::bind(&Foo::doWithParameter, foo, std::placeholders::_1);
Removing const from a decltype result
const int CONST_INT = 0;
std::decay<decltype(CONST_INT)>::type _NORMAL_INT = 5;
Using std::enable_if to conditionally compile functions / class members
template<typename T, typename std::enable_if<std::is_arithmetic<T>::value, int>::type = 0>
static size_t getSize(const T & value)
{
return sizeof(T);
}
template<typename T, typename std::enable_if<std::is_same<std::string, T>::value, int>::type = 0>
static size_t getSize(const T & value)
{
return value.size();
}
The trick is that default parameters are not part of the signature of the template. This can be used for class member functions too:
template <typename T>
class Foo
{
template<typename U = T, typename std::enable_if<std::is_same<U, int>::value, int>::type = 0>
static U get()
{
...
}
template<typename U = T, typename std::enable_if<std::is_same<U, double>::value, int>::type = 0>
static U get()
{
...
}
};