Skip to content

Instantly share code, notes, and snippets.

@crcrpar
Created August 1, 2020 15:36
Show Gist options
  • Save crcrpar/a4492dfc1be6624b2aed301a00101640 to your computer and use it in GitHub Desktop.
Save crcrpar/a4492dfc1be6624b2aed301a00101640 to your computer and use it in GitHub Desktop.
Some epitome-ish code snippets from CppCon 2018: Nicolai Josuttis "The Nightmare of Initialization in C++"
// https://youtu.be/7DTlWPgX6zs
// x86-64 Clang 9
// opts: either `-std=c++17 --pedantic-errors` or `-std=c++14 --pedantic-errors`
#include <vector>
#include <string>
#include <atomic>
long long getLongInt();
struct C{};
struct C getC();
struct BaseData {
std::string name;
double value;
};
struct Data : BaseData {
bool used;
};
int main() {
int i1;
int i2 = 42;
int i3(42);
int i4 = int();
int i5{42};
int i6 = {42};
int i7{};
int i8 = {};
auto i9 = 42;
auto i10{42}; // inits int with 42
auto i11 = {42}; // inits std::initializer_list<int> with 42
auto i12 = int{42};
int i13();
int i14(7, 9);
int i15 = (7, 9);
int i16 = int(7, 9);
auto i17(7, 9);
auto i18 = (7, 9);
auto i19 = int(7, 9);
using namespace std::literals;
auto x = "42"s;
std::atomic<int> a{9};
auto a1 = std::atomic<int>{9}; // fixed in C++17
std::array<int, 5> r{};
auto r1 = std::array{}; // expensive till C++17
long long ll{getLongInt()};
auto ll1 = long long {getLongInt()};
auto ll2 = int64_t(getLongInt());
auto ll3 = static_cast<long long>(getLongInt());
const C & r = getC();
auto r1 = static_cast<const C&>(getC());
auto & r = static_cast<const C&>(getC());
auto && r = static_cast<const C&>(getC());
// `auto` decays:
// - Raw arrays convert to pointers
// - Functions convert to function pointers
// - Top-level references are removed
// - Top-level `const/volatile` qualifiers are removed
// as passing arguments by value
int i = 42;
const int & r = i; // `r` has type `const int &` and refers to `i`
auto v = r; // `v` has type `int` and is a new object;
const int arr[4] = {1, 2, 3, 4};
auto a = arr; // `a` has type `const int *`
auto s = "hi"; // `s` has type `const char*`, `"hi"` has type `const char[3]`
// {...} disables implicit narrowing
int iii = 7.8;
int iii2 = {7.8};
unsigned int x1 = -17;
unsigned int x2{-17};
std::vector<int> v1{1, 2.3, 4, 5.6};
double d{-1.23456};
std::vector<int> v2{d}; // narrowing warning
char c{'a'};
char c1{c + 1};
char c3{static_cast<char>(c+1)};
char c2 = c+1;
char c3(c+1);
// {...} can be used as initializer list
// - to pass multiple parameters to ordinary constructors
// - different types are allowed
// - as an std::initializer_list<>
// - must be homogeneous
// - only for {...}
// () initialization for ordinary constructors only
// {} initialization for *all* constructors
// - std::initializer_list<> constructors have higher priority
// - But the default constructor has highest priority
std::vector<std::string> v00 = "1"; // ERROR
std::vector<std::string> v01 = {}; // OK since C++14
std::vector<std::string> v02 = {"1"};
std::vector<std::string> v03 = {"1", "2"};
std::vector<std::string> v04 = {{{"1"}, {"2"}}};
std::vector<std::string> v05 = {{"1", "2", "3"}};
std::vector<std::string> v06 = {{{"1", "2"}}}; // ERROR
std::vector<std::string> v07 = {{"1", "2"}}; // Fatal Runtime Error: taking the two arguments as iterators
// Constructors and type conversion operators define implicit conversions
// `explicit` disables implicit conversions
Data u;
Data v{};
Data x{{"item", 6.7}, false};
Data y{"item", 6.7, false};
}
@crcrpar
Copy link
Author

crcrpar commented Aug 1, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment