STL containers

std::set

You should always prefer member function over an algorithm if good performance is the goal.

1. if you want to change an element in a set container, you must first delete it and then insert the modified version.

2. fill container with values from standard input

std::vector data;
std::copy(std::istream_iterator(std::cin), std::istream_iterator(), std::back_inserter(data));
std::copy(std::begin(data), std::end(data), std::ostream_iterator(std::cout, " "));

2a. fill container with values from standard file (integers, space separated), sort, write to file

std::ifstream fin("input.txt");
std::ofstream fout("output.txt");
std::vector<int> v;
std::copy(std::istream_iterator<int>(fin), std::istream_iterator<int>(), std::inserter(v, v.end()));
std::sort(v.begin(), v.end());
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(fout, " "));

3. use emplace_back instead of push_back

std::vector data;
data.push_back("abc");//calls string constructor & moves the string
data.emplace_back("def");//calls string constructor to create element in place

4. erase-remove idiom
after remove() call size() would still return pre-removed number of elements. erase() should be called to clear the memory:

std::vector data{ "one", "none", "two", "none", "three" };
int nSize = data.size(); // -> 5
auto it = std::remove(std::begin(data), std::end(data), "none");
nSize = data.size(); // -> 5
data.erase(it, std::end(data));
nSize = data.size(); // -> 3


// or
data.erase(std::remove(std::begin(data), std::end(data), "none"), std::end(data));

5. std::map
the insert() function member returns a pair<iterator, bool=””> object. The first member to the object is an iterator that points either to the element that was inserted, or to the element that prevented its insertion. The latter will be the case if an object has already been stored in the map with the same key. The second member of the object that is returned is a bool value that will be true if the insertion was successful, and false otherwise.

6. std::multimap

std::multimap<std::string, size_t=""> people{{"Ann",25},{"Bill",46},{"Jack",77},{"Jack",32},{"Jill",32},{"Ann",35}};
auto pt = people.equal_range("Ann");
if(pt.first != std::end(people)) {
    for(auto it = pt.first; it != pt.second; ++it)
        std::cout << it->first << " is " << it->second << std::endl;
    }
}

7. Comparison Functions
You must not use <= or >= comparisons!
A map or multimap containers uses equivalence to determine when keys are equal. Two keys, key1 and key2, are equivalent and therefore considered to be equal if the expression key1 < key2 and key2 < key1 both result in false:

!(key1 < key2) && !(key2 < key1) -> true

8. read text file with a list of people: each string is a record, space separated of last, first name, age; sort; write to file; print records of people 20 to 25 years old:

struct person{
    std::string firstname, lastname;
    size_t age;
};

std::ostream& operator << (std::ostream& out, const person& p){
    out << p.firstname << " " << p.lastname << " " << p.age;
    return out;
}

std::istream& operator >> (std::istream& in, person& p){
    in >> p.firstname >> p.lastname >> p.age;
    return in;
}

bool comparator(const person& p1, const person& p2){
    return p1.age < p2.age;
}

struct predicate{
    size_t begin, end;
    predicate(int p1, int p2): begin(p1), end(p2) {}
    bool operator ()(const person& p){
        return (p.age > begin) && (p.age < end);
    }
};

std::ifstream fin("input.txt");
std::ofstream fout("output.txt");
std::vector<person> v;
std::copy(std::istream_iterator<person>(fin), std::istream_iterator<person>(), std::inserter(v, v.end()));
std::sort(v.begin(), v.end(), comparator);
std::copy_if(v.begin(), v.end(), std::ostream_iterator<person>(std::cout, "\n"), predicate(20, 25));
std::copy(v.begin(), v.end(), std::ostream_iterator<person>(fout, "\n"));

some useful tips (mostly for myself)