So I have started updating myself with Modern C++ a while ago & since my post 21 new features of Modern C++ to use in your project & All about lambda function in C++ was popular I decided to write about advanced C++ concepts & idioms which I have learned from this wikibook & course.
/!\: Originally published @ www.vishalchovatiya.com.
There are many other advanced C++ concepts & idioms as well but I would consider these 7 as "should-know". To explain them, I have taken a more pragmatic approach than sophistication. And weighed more on readability, simplicity over other fancy features, syntax sugars and complexity.
Note: There are also drawbacks of using some of these techniques which I have not discussed here or maybe I am not qualified enough.

1. RAII

Intent: To guarantee the release of resource(s) at the end of a scope.
Implementation: Wrap resource into a class; resource acquired in the constructor immediately after its allocation; and automatically released in the destructor; resource used via an interface of the class;
Also known as: Execute-around object, Resource release is finalization, Scope-bound resource management.
Problem
struct resource
{
    resource(int x, int y) { cout << "resource acquired\n"; }
    ~resource() { cout << "resource destroyed\n"; }
};

void func()
{
    resource *ptr = new resource(1, 2);
    int x;
    std::cout << "Enter an integer: ";
    std::cin >> x;
    if (x == 0)
        throw 0; // the function returns early, and ptr won't be deleted!
    if (x < 0)
        return; // the function returns early, and ptr won't be deleted!
    // do stuff with ptr here
    delete ptr;
}
Solution
template<class T>
class smart_ptr
{
    T* m_ptr;
public:
    template<typename... Args>
    smart_ptr(Args&&... args) : m_ptr(new T(std::forward<Args>(args)...)){}
    ~smart_ptr() { delete m_ptr; }

    smart_ptr(const smart_ptr& rhs) = delete;
    smart_ptr& operator=(const smart_ptr& rhs) = delete;

    smart_ptr(smart_ptr&& rhs) : m_ptr(exchange(rhs.m_ptr, nullptr)){}
    smart_ptr& operator=(smart_ptr&& rhs){        
        if (&rhs == this) return *this;
        delete m_ptr;
        m_ptr = exchange(rhs.m_ptr,nullptr);
        return *this;
    }
    T& operator*() const { return *m_ptr; }
    T* operator->() const { return m_ptr; }
};

void func()
{
    auto ptr = smart_ptr<resource>(1, 2); // now ptr guarantee the release of resource
    // ...
}
Use cases

2. Return Type Resolver

Intent: To deduce the type of the object being initialized or assigned to.
Implementation: Uses templatized conversion operator.
Also known as: Return type overloading
Issue
int from_string(const char *str) { return std::stoi(str); }
float from_string(const char *str) { return std::stof(str); } // error
Solution
class from_string
{
    const string m_str;
public:
    from_string(const char *str) : m_str(str) {}
    template <typename type>
    operator type(){
        if constexpr(is_same_v<type, float>)        return stof(m_str);
        else if (is_same_v<type, int>)              return stoi(m_str);
    }
};

int n_int = from_string("123");
float n_float = from_string("123.111");
// Will only work with C++17 due to `is_same_v`
If you are unaware of constexpr, I have written a short post on when to use const vs constexpr in c++.
Use cases

3. Type Erasure

Intent: To create generic container that can handle a variety of concrete types.
Implementation: Can be implemented by void*, templates, polymorphism, union, proxy class, etc.
Also known as: Duck-typing
Problem
Different Type Erasure Techniques
=> Type erasure using void* (like in C)
void qsort (void* base, size_t num, size_t size,
            int (*compare)(const void*,const void*));
Drawback: not safe & separate compare function needed for each type
=> Type erasure using templates
template <class RandomAccessIterator>
  void sort(RandomAccessIterator first, RandomAccessIterator last);
Drawback: may lead to many function template instantiations & longer compilation time
=> Type erasure using polymorphism
struct base { virtual void method() = 0; };
struct derived_1 : base { void method() { cout << "derived_1\n"; } };
struct derived_2 : base { void method() { cout << "derived_2\n"; } };
// We don't see a concrete type (it's erased) though can dynamic_cast
void call(base* ptr) { ptr->method(); };
Drawback: run-time cost (dynamic dispatch, indirection, vtable, etc.)
=> Type erasure using union
struct Data {};
union U {
    Data d;         // occupies 1 byte
    std::int32_t n; // occupies 4 bytes
    char c;         // occupies 1 byte
    ~U() {}         // need to know currently active type
}; // an instance of U in total occupies 4 bytes.
Drawback: not type-safe
Solution
struct any 
{
    struct base {};

    template<typename T>
    struct inner: base{
        inner(T t): m_t{std::move(t)} {}
        T m_t;
        static void type() {}
    };

    any(): m_ptr{nullptr}, typePtr{nullptr} {}
    template<typename T>
    any(T && t): m_ptr{std::make_unique<inner<T>>(t)}, typePtr{&inner<T>::type} {}
    template<typename T>
    any& operator=(T&& t){
        m_ptr = std::make_unique<inner<T>>(t); 
        typePtr = &inner<T>::type;
        return *this;
    }
private:
    template<typename T>
    friend T& any_cast(const any& var);

    std::unique_ptr<base> m_ptr = nullptr;
    void (*typePtr)() = nullptr;
};
template<typename T>
T& any_cast(const any& var)
{
    if(var.typePtr == any::inner<T>::type)
        return static_cast<any::inner<T>*>(var.m_ptr.get())->m_t;
    throw std::logic_error{"Bad cast!"};
}
int main()
{
    any var(10);
    std::cout << any_cast<int>(var) << std::endl;
    var = std::string{"some text"};
    std::cout << any_cast<std::string>(var) << std::endl;
    return 0;
}
Use cases

4. CRTP

Intent: To achieve static polymorphism.
Implementation: Make use of base class template specialization.
Also known as: Upside-down inheritance, Static polymorphism
Problem
struct obj_type_1
{
    bool operator<(const value &rhs) const {return m_x < rhs.m_x;}
    // bool operator==(const value &rhs) const;
    // bool operator!=(const value &rhs) const;    
    // List goes on. . . . . . . . . . . . . . . . . . . .
private:
    // data members to compare
};

struct obj_type_2
{
    bool operator<(const value &rhs) const {return m_x < rhs.m_x;}
    // bool operator==(const value &rhs) const;
    // bool operator!=(const value &rhs) const;    
    // List goes on. . . . . . . . . . . . . . . . . . . .
private:
    // data members to compare
};

struct obj_type_3 { ...
struct obj_type_4 { ...
// List goes on. . . . . . . . . . . . . . . . . . . .
Solution
template<class derived>
struct compare {};
struct value : public compare<value> 
{
    value(const int x): m_x(x) {}
    bool operator<(const value &rhs) const { return m_x < rhs.m_x; }
private:
    int m_x;
};

template <class derived>
bool operator>(const compare<derived> &lhs, const compare<derived> &rhs) {
    // static_assert(std::is_base_of_v<compare<derived>, derived>); // Compile time safety measures
    return (static_cast<const derived&>(rhs) < static_cast<const derived&>(lhs));
}

/*  Same goes with other operators
 == :: returns !(lhs < rhs) and !(rhs < lhs)
 != :: returns !(lhs == rhs)
 >= :: returns (rhs < lhs) or (rhs == lhs)
 <= :: returns (lhs < rhs) or (rhs == lhs) 
*/

int main()
{   
    value v1{5}, v2{10};
    cout <<boolalpha<< "v1 == v2: " << (v1 > v2) << '\n';
    return 0;
}
// Now no need to write comparator operators for all the classes, 
// Write only type dependent `operator <` &  use CRTP
Use cases
template<typename specific_animal>
struct animal {
    void who() { implementation().who(); }
private:
    specific_animal& implementation() {return *static_cast<specific_animal*>(this);}
};

struct dog : public animal<dog> {
    void who() { cout << "dog" << endl; }
};

struct cat : public animal<cat> {
    void who() { cout << "cat" << endl; }
};

template<typename specific_animal>
void who_am_i(animal<specific_animal> & animal) {
    animal.who();
}
Update: The above hiccup of declaring multiple comparisons operator will permanently be sorted from C++20 by using spaceship(
<=>
)/Three-way-comparison operator.

5. Virtual Constructor

Intent: To create a copy or new object without knowing its concrete type.
Implementation: Exploits overloaded methods with polymorphic assignment.
Also known as: Factory method/design-pattern.
Problem
struct animal {
    virtual ~animal(){ cout<<"~animal\n"; }
};

struct dog : animal {
    ~dog(){ cout<<"~dog\n"; }
};

struct cat : animal {
    ~cat(){ cout<<"~cat\n"; }
};

void who_am_i(animal *who) { // not sure whether dog would be passed here or cat
    // How to `create` the object of same type i.e. pointed by who ?
    // How to `copy` object of same type i.e. pointed by who ?
    delete who; // you can delete object pointed by who
}
Solution
struct animal {
    virtual ~animal() = default;
    virtual std::unique_ptr<animal> create() = 0;
    virtual std::unique_ptr<animal> clone() = 0;
};

struct dog : animal {
    std::unique_ptr<animal> create() { return std::make_unique<dog>(); }
    std::unique_ptr<animal> clone() { return std::make_unique<dog>(*this); }
};

struct cat : animal {
    std::unique_ptr<animal> create() { return std::make_unique<cat>(); }
    std::unique_ptr<animal> clone() { return std::make_unique<cat>(*this); }
};

void who_am_i(animal *who) {
    auto new_who = who->create();// `create` the object of same type i.e. pointed by who ?
    auto duplicate_who = who->clone(); // `copy` object of same type i.e. pointed by who ?    
    delete who; // you can delete object pointed by who
}
Use cases

6. SFINAE and std::enable_if

Intent: To filter out functions that do not yield valid template instantiations from a set of overloaded functions.
Implementation: Achieved automatically by compiler or exploited using std::enable_if.
Motivation
template<class T>
void func(T* t){ // Single overload set
    if constexpr(std::is_class_v<T>){ cout << "T is user-defined type\n"; }
    else { cout << "T is primitive type\n"; }
}

int primitive_t = 6;
struct {char var = '4';} class_t;


func(&class_t);
func(&primitive_t);
Solution
template<class T, typename = std::enable_if_t<std::is_class_v<T>>>
void func(T* t){
    cout << "T is user-defined type\n";
}

template<class T, std::enable_if_t<std::is_integral_v<T>, T> = 0>
void func(T* t){ // NOTE: function signature is NOT-MODIFIED
    cout << "T is primitive type\n";
}
Use cases
// Stolen & trimmed from https://stackoverflow.com/questions/982808/c-sfinae-examples.
template<typename T>
class is_class_type {
    template<typename C> static char test(int C::*);    
    template<typename C> static double test(...);
public:
    enum { value = sizeof(is_class_type<T>::test<T>(0)) == sizeof(char) };
};

struct class_t{};

int main()
{
    cout<<is_class_type<class_t>::value<<endl;    // 1
    cout<<is_class_type<int>::value<<endl;        // 0
    return 0;
}

7. Proxy

Intent: To achieve intuitive functionality using middleware class.
Implementation: By use of temporary/proxy class.
Also known as: 
operator []
(i.e. subscript) proxy, double/twice operator overloading
Motivation
operator [ ] solution
template <typename T = int>
struct arr2D{
private:
    struct proxy_class{
        proxy_class(T *arr) : m_arr_ptr(arr) {}
        T &operator[](uint32_t idx) { return m_arr_ptr[idx]; }
    private:
        T *m_arr_ptr;
    };
    T m_arr[10][10];
public:
    arr2D::proxy_class operator[](uint32_t idx) { return arr2D::proxy_class(m_arr[idx]); }
};

int main()
{
    arr2D<> arr;
    arr[0][0] = 1;
    cout << arr[0][0];
    return 0;
}
Use cases

Summary by FAQs

When to actually use RAII?
Why can't functions be overloaded by return type?
When to use return type resolver idiom?
What is type erasure in C++?
Best scenarios to apply type erasure idiom?
What is the curiously recurring template pattern (CRTP)?
Why Curiously Recurring Template Pattern (CRTP) works?
What is SFINAE?
What is Proxy Class in C++?
Why do we not have a virtual constructor in C++?
Can we make a class copy constructor virtual in C++?
What are the use cases & need for virtual constructor?