I usually will use a range-based for (for(auto& n : nums)) instead of for_each
Containers
Sequence containers
Sequence containers implement data structures which can be accessed sequentially.
name
description
array
static contiguous array
vector
dynamic contiguous array
deque
double-ended queue
forward_list
singly-linked list
list
doubly-linked list
Associative containers
Associative containers implement sorted data structures that can be quickly searched (O(log n) complexity).
name
description
set
collection of unique keys, sorted by keys
map
collection of key-value pairs, sorted by keys, keys are unique
multiset
collection of keys, sorted by keys
multimap
collection of key-value pairs, sorted by keys
Unordered associative containers
Unordered associative containers implement unsorted (hashed) data structures that can be quickly searched (O(1) amortized, O(n) worst-case complexity).
name
description
unordered_set
collection of unique keys, hashed by keys
unordered_map
collection of key-value pairs, hashed by keys, keys are unique
unordered_multiset
collection of keys, hashed by keys
unordered_multimap
collection of key-value pairs, hashed by keys
Container adaptors
Container adaptors provide a different interface for sequential containers.
name
description
stack
adapts a container to provide stack (LIFO data structure)
queue
adapts a container to provide queue (FIFO data structure)
priority_queue
adapts a container to provide priority queue
Span (C++20)
name
description
span
a non-owning view over a contiguous sequence of objects
Most modifiers are not supported such as push_back
vector
The storage of the vector is handled automatically, being expanded and contracted as needed.
The elements are stored contiguously.
Element access, capacity, container operations and ranged-loops are supported
Creation
Modifiers
deque
deque (double-ended queue) is an indexed sequence container that allows fast insertion and deletion at both its beginning and its endO(1)
not stored contiguously
Expansion of a deque is cheaper than the expansion of a std::vector
cons: large minimal memory cost
Random access - O(1)
Element access, capacity, container operations and ranged-loops are supported
A deque is somewhat recursively defined: Internally it maintains a double-ended queue of chunks of fixed size. Each chunk is a vector, and the queue (“map” in the graphic below) of chunks itself is also a vector.
Difference between std::pair and std::tuple with only two members?
std::pair can only have two values - not zero, one, three or more
It's a bit easier to get the contents of a pair than a tuple. You have to use a function call in the tuple case: get<0>(t), while the pair case is just a member field (p.first,p.second)
Unpacking
auto [x,y] = f_pair() Creates this implicitly
Unpacking Structed Bindings
Allows unpacking any data structure whose size is known during compile time
template<>
int foo<__lambda_9_27>(int x, int y, __lambda_9_27 lambda){
return lambda.operator()(x, y);
}
int main(){
struct __lambda_9_27{
int operator()(int x, int y) const{
return x * y;
}
}
std::cout.operator<<(foo(2, 3, __lambda_9_27{})).operator<<(std::endl);
}
#include <iostream>
#include <vector>
#include <algorithm> //std::any_of
using namespace std;
int main(){
vector<int> v {1,2,3,4,-1};
// Checking if any element is negative
any_of(v.cbegin(), v.cend(), [](int x){ return x<0; }) ? cout << "There exists a negative element\n" :cout << "All are positive elements\n";
int N=2;
cout << count_if(v.begin(), v.end(),[N](int a){ return (a >= N);}) <<endl;
return 0;
}
There exists a negative element
3
set<int, less<int> > s ={1,3,3,4,-1};
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int, less<int> > s ={1,3,3,4,-1}; // std::greater<int>
s.insert(-5);
s.erase(1);
for(const auto& v: s)
std::cout << v << ' '; cout<<endl;
}
-5 -1 3 4
multiset<int, greater<int> > s ={1,3,3};
#include <iostream>
#include <set>
using namespace std;
int main() {
multiset<int, greater<int> > s ={1,3,3,-1};
for(const auto& v: s)
std::cout << v << ' '; cout<<endl;
}
3 3 1 -1
map<int, int> m;
#include <iostream>
#include <map>
using namespace std;
int main() {
map<int, int> m;
// insert elements in random order
m.insert(pair<int, int>(3, 60));
m.insert(pair<int, int>(1, 40));
m.insert(pair<int, int>(2, 30));
m.erase(2); // remove elems with key=2
for(const auto& v: m)
std::cout << v.first << ": " << v.second << endl;
}
1: 40
3: 60
#include <iostream>
#include <map>
#include <string>
using std::map; using std::cout; using std::string;
int main(){
map<string, string> address_book = { std::make_pair("one","0123"),std::make_pair("two","4567") };
address_book.insert({ "three", "7657" });
for (auto & address_entry : address_book){
cout << address_entry.first << " | " << address_entry.second << " |" << std::endl;
}
return 0;
}
#include <iostream>
#include <span>
using namespace std;
void printSpan(std::span<int> s){
for (auto& i : s)
cout << i < " "; cout <<endl;
//std::find_if(s.begin(), s.end(),some_predicate);
}
int main() {
int a[5]={0,1,2,3,4,5};
printSpan(a);
return 0;
}
#include <iostream>
#include <tuple>
using namespace std;
auto f_pair() {
return pair(5,"hello");
// return tuple(5,"hello");
}
int main() {
auto f = f_pair; // f is a pointer to function
auto [i,j] = f();
cout << i << " " << j << endl;
auto [x,y] = f_pair();
cout << x << " " << y << endl;
}