C++ standard

1. Initialization

– As a class author, you need to be aware that if your set of overloaded constructors includes one or more functions taking a std::initializer_list, client code using braced initialization may see only the std::initializer_list overloads. As a result, it’s best to design your constructors so that the overload called isn’t affected by whether clients use parentheses or braces. In other words, learn from what is now viewed as an error in the design of the std::vector interface, and design your classes to avoid
– The second lesson is that as a class client, you must choose carefully between parentheses and braces when creating objects.

depending on initialization syntax different constructors would be called:

std::vector<int> v1(10, 20);  // use non-std::initializer_list ctor: create 10-element vector, all elements have value of 20
std::vector<int> v2{10, 20};  // use std::initializer_list ctor: create 2-element vector, element values are 10 and 20

2. enums

enum class Color { black, white, red }; // black, white, red are scoped to Color
auto white = false; // fine, no other “white” in scope
Color c = white; // error! no enumerator named “white” is in this scope
Color c = Color::white; // fine
auto c = Color::white; // also fine 

// enum class could be forward declared
enum class Status; // forward declaration
void continueProcessing(Status s); // use of fwd-declared enum

// enum class could not be converted into int, so we can create template to help us with that:
template<typename E> constexpr typename std::underlying_type<E>::type toUType(E enumerator) noexcept
  return static_cast<typename std::underlying_type<E>::type>(enumerator);
// usage example:
auto val = std::get<toUType(UserInfoFields::uiEmail)>(uInfo);

3. tuple

class Name {};
auto my_tuple = std::make_tuple(Name{"Peter", "Piper"}, 42, std::string{"781-606"});
Name name{};
size_t age{};
std::string phone{};
std::tie(name, age, phone) = my_tuple;

// or
std::tie(name, std::ignore, phone) = my_tuple;

4. Defining a Deleter

std::shared_ptr<string> pS(new string("some string"),
[](string* p) { delete p; });

std::shared_ptr<int> p(new int[10],
[](int* p) { delete[] p; });

std::shared_ptr<int> p(new int[10], std::default_delete<int[]>());

5. Function Type Wrappers

void func(int x, int y);

std::vector<std::function<void(int,int)>> tasks;

tasks.push_back([](int x, int y) {});

for(std::function<void(int,int)> f : tasks) {
    f(33, 66);


class C {
    void memfunc(int x, int y) const;

std::function<void(const C&,int,int)> mf;
mf = &C::memfunc;
mf(C(), 42, 77);

some useful tips (mostly for myself)