CPP


https://github.com/yuchdev/CppBooks

General

regex (C++11)

auto variables

Links:

vector

#include<iostream>
#include<vector>

int main() {
    std::vector<int> v1 = {1, 2, 3};
    std::cout << v1[0] << std::endl;  // 1

    std::vector<int> v2(3);
    std::cout << v2[0] << std::endl;  // 0

    std::vector<bool> v3(3);
    std::cout << v3[0] << std::endl;  // 0
}

tuple

https://en.cppreference.com/w/cpp/utility/tuple

An example adapted from cppreference:

#include<iostream>
#include<tuple>

int main() {
    std::tuple<int, char, std::string> ics;
    ics = {5, 'a', "hello"};

    std::cout << "ics[0]: " << std::get<0>(ics) << std::endl;
    std::cout << "ics[1]: " << std::get<1>(ics) << std::endl;
    std::cout << "ics[2]: " << std::get<2>(ics) << std::endl;

    // Getting values in a tuple to vars.
    // Types auto-inferred due to the 'auto' use.
    // The is a C++17 feature named 'structured binding'.
    // GCC (>=7 only) needs -std=c++17
    auto [ival, cval, sval] = ics;

    std::cout << std::endl;
    std::cout << "ival: " << ival << std::endl;
    std::cout << "cval: " << cval << std::endl;
    std::cout << "sval: " << sval << std::endl;

    // Could also be done with std::tie for tuple, but is more verbose.
    int ival2;
    char cval2;
    std::string sval2;
    std::tie(ival2, cval2, sval2) = ics;

    std::cout << std::endl;
    std::cout << "ival2: " << ival2 << std::endl;
    std::cout << "cval2: " << cval2 << std::endl;
    std::cout << "sval2: " << sval2 << std::endl;
}

/*
ics[0]: 5
ics[1]: a
ics[2]: hello

ival: 5
cval: a
sval: hello

ival2: 5
cval2: a
sval2: hello
*/

Similar:

Structured binding (C++17)

Allows the constitutent values of a compound type to be assigned to variables.

See:

Template meta-programming (TMP)

An example from the internet:

template<int Depth, int A, typename B>
struct K17 {
static const int x =
K17 <Depth+1, 0, K17<Depth,A,B> >::x
+ K17 <Depth+1, 1, K17<Depth,A,B> >::x
+ K17 <Depth+1, 2, K17<Depth,A,B> >::x
+ K17 <Depth+1, 3, K17<Depth,A,B> >::x
+ K17 <Depth+1, 4, K17<Depth,A,B> >::x;
};
template <int A, typename B>
struct K17 <16,A,B> {
    static const int x = 1;
};
static const int z = K17 <0,0,int>::x;
int main(void) { }

See:

Original program

(Thanks to Kevin for introducing me to this.)

The example program which drew lot of attention to TMP in C++: http://www.erwin-unruh.de/primorig.html

The original version is no longer valid CPP, but a version here works.

#ifndef LAST
#define LAST 18
#endif

enum {
    IS_PRIME,
    NO_PRIME,
    CONTINUE  
};

template <int candidate, int testValue>
struct Eval {
    enum { 
        mode = 
            testValue * testValue > candidate ? IS_PRIME  :    
            candidate % testValue == 0 ?        NO_PRIME  :
                                                CONTINUE
    };
};

template <int candidate, int prime, int mode >
struct sieve {
    enum { 
        next = prime + 1,
        isPrime = sieve<candidate, next, 
                        Eval<candidate, next>::mode>::isPrime
    };
};

template <int candidate, int prime> 
struct sieve<candidate, prime, IS_PRIME> {
    enum { isPrime = IS_PRIME };
};

template <int candidate, int prime>
struct sieve<candidate, prime, NO_PRIME > {
    enum { isPrime = NO_PRIME };
};

template <int prime>
struct test {
    enum {isPrime = sieve<prime, 2, Eval<prime, 2>::mode>::isPrime };
};

template <int prime, int isPrime>
struct show {                           
    static void f() {
        show<prime - 1, test<prime - 1>::isPrime >::f();
    }
};

template <int prime>
struct show<prime, IS_PRIME> {
    static int *f() {
        show<prime - 1, test<prime - 1>::isPrime >::f();

        int x;
        return &x;
    }
};

template <>
struct show<1, IS_PRIME> {
    static void f() {}
};

template <int prime>
void primes() {
    show<prime, test<prime>::isPrime>::f();
}

int main() {
    // 'instantiation' messages because of the suggested grep command
    static_assert(LAST >= 2, 
        "instantiation of LAST must be >= 2");

    primes<LAST>();

    static_assert(0, 
        "instantiation of compilation terminated");
}

Run with:

$ g++ input.cpp -DLAST=30 2>&1 | grep 'instantiation of'

input.cpp: In instantiation of ‘static int* show<prime, 0>::f() [with int prime = 29]’:
input.cpp: In instantiation of ‘static int* show<prime, 0>::f() [with int prime = 23]’:
input.cpp: In instantiation of ‘static int* show<prime, 0>::f() [with int prime = 19]’:
input.cpp: In instantiation of ‘static int* show<prime, 0>::f() [with int prime = 17]’:
input.cpp: In instantiation of ‘static int* show<prime, 0>::f() [with int prime = 13]’:
input.cpp: In instantiation of ‘static int* show<prime, 0>::f() [with int prime = 11]’:
input.cpp: In instantiation of ‘static int* show<prime, 0>::f() [with int prime = 7]’:
input.cpp: In instantiation of ‘static int* show<prime, 0>::f() [with int prime = 5]’:
input.cpp: In instantiation of ‘static int* show<prime, 0>::f() [with int prime = 3]’:
input.cpp: In instantiation of ‘static int* show<prime, 0>::f() [with int prime = 2]’:

Constraints and concepts (C++20)

Miscellaneous