you-dont-know-cpp
you-dont-know-cpp copied to clipboard
You don't know C++
-
How are these two functions different?
template<typename T> T mkT1() { return {}; } template<typename T> T mkT2() { return T {}; }Hint
Besides the obvious difference in handling of explicit vs nonexplicit default constructors, consider `std::mutex` and C++14 vs C++17. -
Is this code valid?
struct Foo { int a; Foo() = delete; Foo(int) = delete; }; int main() { Foo foo1 {}; Foo foo2 { 10 }; }Answer
Depends on the C++ version.Up until C++17, both variables are initialized with aggregate initialization.
Foo fooandFoo foo(10)wouldn't be valid, though.Starting with C++20, this somewhat counter-intuitive behaviour is fixed, and this code no longer compiles.
-
What does this code do, and on what features of C++17 does it rely?
template<typename F, typename... Ts> void foo(F f, Ts... ts) { int _; (_ = ... = (f(ts), 0)); }Answer
1. It calls the function on the elements of the variadic pack in reverse order. 2. The features are left as an exercise for the reader.What problems does this code have, and what should be done to fix them?
Hint
fmight return something with an overloadedoperator,. -
Assume the following declarations:
template <typename T> concept Trivial = std::is_trivial_v<T>; template <typename T, typename U> requires Trivial<T> void f(T t, U u) { std::cout << 1; } template <typename T, typename U> requires Trivial<T> && Trivial<U> void f(T t, U u) { std::cout << 2; }Is
f(1, 2)valid? If yes, what would it print?-
What if
Trivial<T> && Trivial<U>is replaced byTrivial<T> && Trivial<T>in the second definition? -
What about
Trivial<T> || Trivial<U>? -
What if the definition of
Trivialgets "inlined", replacing allTrivial<T>s withsd::is_trivial_v<T>?
-
-
Assume an instance of a
structismemseted to zeroes. What would be the value of the padding?
Further assume a field of that structure is updated. What would be the value of the padding after that field? After other fields?Answer
Unspecified, unspecified. -
Is this code valid?
char arr[5] = { 0 }; auto pastEnd = arr + 10;What about this one?
char arr[5] = { 0 }; auto pastEnd = arr + 5; -
Which lines are UB, if any?
#include <iostream> struct Foo1 { int a; }; struct Foo2 { int a; Foo2() = default; }; struct Foo3 { int a; Foo3(); }; Foo3::Foo3() = default; int main() { Foo1 foo11, foo12 {}; Foo2 foo21, foo22 {}; Foo3 foo31, foo32 {}; std::cout << foo11.a << std::endl; std::cout << foo12.a << std::endl; std::cout << foo21.a << std::endl; std::cout << foo22.a << std::endl; std::cout << foo31.a << std::endl; std::cout << foo32.a << std::endl; }