mediumSFINAE and enable_if
#include <type_traits>
template <typename T, typename = void>
struct has_size : std::false_type {};
template <typename T>
struct has_size<T, std::void_t<decltype(std::declval<T>().size())>>
: std::true_type {};
Read the full question →mediumcustom allocators
template <typename T>
struct MyAlloc {
using value_type = T;
T* allocate(std::size_t n);
void deallocate(T*, std::size_t);
template <typename U> struct rebind { using other = MyAlloc<U>; };
};
Read the full question →easyfundamental types and auto
auto x = 3.14;
auto y = 42;
Read the full question →easyreferences vs pointers
void f(int p[]) {
std::cout << sizeof(p) << " ";
}
int arr[10];
std::cout << sizeof(arr) << " "; // (1)
f(arr); // (2)
Read the full question →easyfundamental types and auto
for (auto e : v) {
// ...
}
Read the full question →easyreferences vs pointers
int a = 10;
int b = 20;
int& r = a;
r = b;
b = 99;
Read the full question →mediumoptional variant any
std::optional<int> a; // disengaged
bool r = (a < 5);
Read the full question →easyconst correctness
struct Counter {
int value = 0;
int get() const { return value; }
void bump() { ++value; }
};
void show(const Counter& c) {
std::cout << c.get();
c.bump();
}
Read the full question →easyconst correctness
void a(const std::string& s);
void b(std::string& s);
Read the full question →mediumperfect forwarding std::forward
auto fwd = [](auto&&... args) {
return g(std::forward<decltype(args)>(args)...);
};
Read the full question →mediumunique_ptr
#include <memory>
#include <vector>
std::unique_ptr<int> make() {
return std::make_unique<int>(42);
}
int main() {
std::vector<std::unique_ptr<int>> v;
std::unique_ptr<int> p = make();
v.push_back(p);
}
Read the full question →mediumperfect forwarding std::forward
template <typename T>
void target(T&&) { /* ... */ }
template <typename T>
void wrap(T&& arg) {
target(std::forward<T>(arg));
target(std::forward<T>(arg));
}
wrap(42);
Read the full question →mediumperfect forwarding std::forward
template <typename T>
void f(T&& x);
const int c = 0;
f(c);
Read the full question →mediumcustom allocators
std::array<std::byte, 1024> buf;
std::pmr::monotonic_buffer_resource res{buf.data(), buf.size()};
void* p1 = res.allocate(64);
res.deallocate(p1, 64);
void* p2 = res.allocate(64);
Read the full question →mediumconcepts basics
#include <concepts>
void process(std::integral auto x); // (1)
void process(std::signed_integral auto x); // (2)
process(42);
Read the full question →mediumconcepts basics
template <typename T>
concept HasParts = requires(T t) {
typename T::value_type;
t.begin();
};
Read the full question →mediumvariadic templates
void process() {} // base case
template <typename T, typename... Rest>
void process(T first, Rest... rest) {
handle(first);
process(rest...); // recurse on tail
}
Read the full question →mediumvariadic templates
#include <cstdio>
template <typename... Ts>
void print(Ts... xs) {
((std::printf("%d ", xs)), ...);
}
int main() { print(1, 2, 3); }
Read the full question →mediumranges library
std::vector<int> v{1,2,3,4,5};
auto r = v | std::views::filter([](int n){ return n % 2 == 0; })
| std::views::transform([](int n){ return n * n; });
Read the full question →mediumnoexcept
struct A {
A() = default;
A(A&&) noexcept(false) { /* ... */ }
A(const A&) { /* ... */ }
};
std::vector<A> v; // grows past capacity
Read the full question →