CppOnline26 Quiz Hunt
I had great fun attending the CppOnline conference and going through the Gathertown space to find and solve as many questions as I could. I ended up placing 2nd on the leaderboard (and still got the prize anyway, since 1st already had a CLion license!), and there was just one question I couldn't find for the life of me. I asked and was told after the fact that the last question was in a hidden coffee cup as you leave the lobby to go to the poster room, and could only be interacted with in a specific position. Though the Gathertown space is no longer accessible, the following is everything I found with location screenshots, in the order I found them in. I quite enjoyed finding all the Easter eggs and hidden rooms in the space, and I hope reading through this can bring you a sliver of the fun I experienced while hunting these locations down! I certainly also learned I need to refresh my understanding of move semantics, so expect a post soon about that.
- Location: main hall billiard ball on table
Question: According to the C++23 standard, what is the guaranteed output of this program?
#include <iostream> #include <map> bool default_constructed = false; bool constructed = false; bool assigned = false; class C { public: C() { default_constructed = true; } C(int) { constructed = true; } C& operator=(const C&) { assigned = true; return *this;} }; int main() { std::map<int, C> m; m[7] = C(1); std::cout << default_constructed << constructed << assigned; }
Answer: 111
Solution:
m[7]looks for the key7and doesn't find it, sostd::map::operator[]value initializes aCobject via the default constructor and returns a reference. Then the right hand side,C(1)explicitly calls the parameterized constructor and gives a temporaryC(1), and the=operator takes that temporary to overwrite the default-constructedCfrom the left hand side. As an aside,std::map::try_emplace(C++17) andstd::map::emplace(C++11) can construct the object directly in the map's memory without needing to make a temporary copy:std::map::emplace(C++11) is clunkier becausestd::mapexpects astd::pair<const Key, Value>, so to really avoid temporaries you have to go piecewise:m.emplace(std::piecewise_construct, std::forward_as_tuple(7), std::forward_as_tuple(1));
std::map::try_emplace(C++17) checks if the key exists first. If it does, the constructor arguments aren't looked at; if it doesn't, then the value is constructed in place:m.try_emplace(7, 1);This is CppQuiz question #208.
- Location: Social room, thing next to Booking object
Question: According to the C++23 standard, what is the output of this program?
#include <iostream> class A { public: A() { std::cout << "A"; } A(const A &) { std::cout << "a"; } }; class B: public virtual A { public: B() { std::cout << "B"; } B(const B &) { std::cout << "b"; } }; class C: public virtual A { public: C() { std::cout << "C"; } C(const C &) { std::cout << "c"; } }; class D: B, C { public: D() { std::cout << "D"; } D(const D &) { std::cout << "d"; } }; int main() { D d1; D d2(d1); }
Answer: ABCDABCd
Solution: The order of virtual inheritance initialization happens as such: The most derived class is responsible for initializing the virtual base, and then the direct bases are initialized in the order they are declared, and then the body of the most derived class's constructor runs. So in the case of
D d1;, the outputs would beABCDin that order. Then ford2copy construction:D(const D&)gets called, but this copy constructor doesn't explicitly initialize the base classes in the initializer list, so the compiler will default to calling the default constructors of the bases. Thus, the second set of outputs isABCd. Aside: If you wanted, e.g.,ABCDabcd, you'd need to explicitly chain together copy constructors like so:D(const D &other) : A(other), B(other), C(other) { std::cout << "d"; }. Note that the ordering ofabcdis still defined by class definition, not initializer list order, due to virtual inheritance. In a normal hierarchy,Bwould initializeA, etc.
- Location: Upper right lightning talk corner in lobby
Question: What is the guaranteed output of this program?
#include <iostream> struct Base { virtual int f() = 0; }; int Base::f() { return 1; } struct Derived : Base { int f() override; }; int Derived::f() { return 2; } int main() { Derived object; std::cout << object.f(); std::cout << ((Base&)object).f(); }
Answer: 22
Solution: The first line will return
2, asDerived'sf()function will be called. Easy enough. The second line is trying to access the sameobjectthrough its base class,Base. SinceBase'sf()function is virtual, the dynamic type ofobjectis what determines whichf()gets called via dynamic dispatch, so it's still theDerived::f(). Notice that the pure virtual function inBaseis still defined, but will never be called due to polymorphism. This is in fact valid by the standard. If you wanted to force theBaseversion of the function, use the scope resolution operator:object.Base::f(). This static binding (call-by-name) requires the function to be declared in theBaseclass but defined outside the class (due to lexical rules, but also best practices), and is still subject to access control (can't be markedprivate). This is Cpp Quiz Question #224.
- Location: Poster room bottom training section, beers
Question: According to the C++23 standard, what is the output of this program?
#include <iostream> #include <type_traits> #include <utility> void g(int&) { std::cout << 'L'; } void g(int&&) { std::cout << 'R'; } template void f(T&& t) { if (std::is_same_v<T, int>) { std::cout << 1; } if (std::is_same_v<T, int&>) { std::cout << 2; } if (std::is_same_v<T, int&&>) { std::cout << 3; } g(std::forward(t)); } int main() { f(42); int i = 0; f(i); }
Answer: 1R2L
Solution: This is looking at forwarding/universal references and reference collapsing.
42is an rvalue and thef(42)call is only comparingstd::is_same_v<int, int>in the first part. Thenstd::forwardcasts42to original rvalue status, which matchesg(int&&), printing1R. In thef(i)call,iis an lvalue. If you pass an lvalue to a forwarding referenceT&&, the compiler uses template argument deduction and deducesTitself as an lvalue referenceint&, so onlystd::is_same_v<int&, int&>is true. Thenstd::forward(t)turnsT&&toint& &&, and under reference collapsing rules& + && = &, so this becomesint&and2Lis printed. As an aside, hadibeenconst, no numbers or letters would've printed (theconst-ness carries through the template argument deduction and reference collapsing).
- Location: track B room, bottom right corner plant
Question: According to the C++23 standard, what is the guaranteed output of this program?
#include <iostream> namespace x { class C {}; void f(const C& i) { std::cout << "1"; } } namespace y { void f(const x::C& i) { std::cout << "2"; } } int main() { f(x::C()); }
Answer: 1
Solution: This is looking at argument-dependent lookup (Koenig lookup). When
f(x::C())is called, there's no namespace specified to look forfin, andfisn't defined globally. Normally the compiler would stop there, but sinceCis defined in thexnamespace (x::C()), ADL also tells the compiler to searchxfor any functions matchingf. The compiler has zero reason to look inside the namespacey, because it hasn't been brought into scope with ausingdirective, nor is the argument associated with that namespace. This is CppQuiz question #196.
- Location: secret room, right side column of 4 food stands, bottom food stand

Question: According to the C++23 standard, what is the guaranteed output of this program?
#include <iostream> int j = 1; int main() { int& i = j, j; j = 2; std::cout << i << j; }
Answer: 12
Solution: In
int& i = j, j;there are two things going on: firstint& i = jcreates a referenceiand aliases it to the globalj. Thenj;declares a localjfor the scope of themainfunction that shadows the globalj. So whenj = 2;happens, the referenceiis still pointing to the globaljwith value1, and the localjgets initialized to2. So the printout is12. Had we used::j = 2instead, the globaljwould've been updated while the localjwas still initialized.
- Location: secret room, hidden private room on the bottom
Question: According to the C++23 standard, what is the output of this program?
#include <iostream> using namespace std; int main() { int a = '0'; char const &b = a; cout << b; a++; cout << b; }
Answer: 00
Solution: We need to be careful thinking about these references to different types.
ais anintand gets set to the ASCII value of0which is48, butbis achar, so the compiler can't directly point the referencebto the memory location ofa. Instead, the compiler does an implicit conversion, copying the value ofainto a temporarycharand binding the referencebto that. Sincebisconst, the lifetime of that temporary is implicitly extended to the lifetime ofb. Then whenais incremented, the temp thatbpoints to is unchanged, so printingbboth times still refers to that temporarychar 0.
- Location: secret room, glowing character hologram near center
Question: According to the C++23 standard, what is the guaranteed output of this program?
#include <iostream> enum A : const int volatile { x, y, z }; int main() { A a = A::x; a = A::y; std::cout << "ok"; }
Answer: ok
Solution: The enum
Ahas an underlyingintdefinition. ReassigningafromA::xtoA::yis fine and everything compiles. You may think thecv-qualified enum definition makes the enum invalid or unassignable, but it still behaves as a normal enum.
- Location: secret room, top left, interact with the mic on stage (Dutch meetup question!)
Question: This C++ Hello World program doesn't seem to print anything. If you could only insert one keyword, which one can be used to fix it?
#include <iostream> class Base { public: ~Base() { } }; class Derived : public Base { public: ~Derived() { std::cout << "Hello world!" << std::endl; } }; int main() { Base* b = new Derived(); delete b; return 0; }
Answer: virtual
Solution: Deletion is happening through a base class pointer (aka polymorphically), so it needs a virtual destructor
virtual ~Base(). Thendelete b;will runDerived::~Derived()andBase::~Base()as expected.
- Location: secret room, left side bottom traffic cone (Dutch meetup question)
Question: What does the code below output?
#include <iostream> int main() { int x = 10; int y = x++ + ++x; std::cout << y << std::endl; return 0; }
Answer: UB
Solution: I originally entered 22 (and this was accepted as an answer!) because I thought that
ywould be summing11fromx++and then11from++x(and thenxwould end up as12), but I actually now think this might be UB as it's not clear what the sequence of modifications onxshould be. In fact, I think this is unsequenced (as opposed to indeterminately sequenced) because+doesn't impose any evaluation order between the side effects from the left and right operands. Indeterminately sequenced means one side is guaranteed to happen before the other, but the standard doesn't say which one. That doesn't hold here in the built-in+operator case.
- Location: secret room, hidden top side of left small building near spawn point
Question: According to the C++23 standard, what is the guaranteed output of this program?
#include <future> #include <iostream> int main() { try { std::promise p; std::future f1 = p.get_future(); std::future f2 = p.get_future(); p.set_value(1); std::cout << f1.get() << f2.get(); } catch(const std::exception& e) { std::cout << 2; } }
Answer: 2
Solution: This is missing that template argument and should look like
std::promise p;but with that, this would print 2.p.get_future()can only be called once per promise, so the second callstd::future f2 = p.get_future()throws astd::future_error (std::future_already_retrieved).
- Location: hallway between lobby and outside, first wall tile on right
Question: According to the C++23 standard, what is the output of this program?
#include <variant> #include <iostream> int main() { std::variant<int, double, char> v; std::cout << v.index(); }
Answer: 0
Solution: A default-constructed variant holds its first alternative (
inthere), andindex()returns the zero-based index of the held alternative.
- Location: secret room, ramen bowl on left side of right ramen shack, next to the two buildings near spawn point
Question: According to the C++23 standard, what is the guaranteed output of this program?
#include <iostream> int main() { int i = 1; int const& a = i > 0 ? i : 1; i = 2; std::cout << i << a; }
Answer: 21
Solution:
i > 0is true, so you would think the referenceagets pointed to the memory location ofi, so22gets printed. But actually, in the ternary operator, since the left sideiis an lvalue (intobject) and the right side1is a prvalue (inttemporary), the compiler needs to choose one of these to be the common result of the ternary. It chooses prvalue because that's the "greatest common factor" when one side is a reference and one is a value. Soint const&ends up binding to a temporary copy, leading to the printout of21. If both branches of the ternary were lvalues, lvalue-ness would be preserved.
- Location: secret room balcony, entered through top left of main room, via elevators behind folding screen, bottom left corner of balcony


Question: According to the C++23 standard, what is the guaranteed output of this program?
#include <iostream> class A { public: virtual void f() { std::cout << "A"; } }; class B : public A { public: void f() { std::cout << "B"; } }; void g(A a) { a.f(); } int main() { B b; g(b); }
Answer: A
Solution:
g(A a)takes the parameter by value, so theg(b)call copies the base subobjectAfromb. This is object slicing. Insideg, we have anAobject, so virtual dispatch uses that dynamic type, andA::f()runs.
- Location: secret room, fireplace near bottom left
Question: According to the C++23 standard, what is the guaranteed output of this program?
#include <iostream> struct A { virtual std::ostream &put(std::ostream &o) const { return o << 'A'; } }; struct B : A { virtual std::ostream &put(std::ostream &o) const { return o << 'B'; } }; std::ostream &operator<<(std::ostream &o, const A &a) { return a.put(o); } int main() { B b; std::cout << b; }
Answer: B
Solution:
std::cout << bcalls the&operator<<(std::ostream &o, const A &a)becausebis-aA(is a subtype of). Then at the virtuala.put(o)call the dynamic type ofahere isB, so dispatch choosesB::put.
- Location: Track C room, sparkly out of place floor cushion above HRT sponsor tile (Dutch meetup question)
Question: Which of these functions does not exist in the C++ Standard?
A. std::get_money()B.std::set_money()C.std::put_money()D.std::money_put()
Answer: B
Solution:
get_money()andput_money()are input/output manipulators for money values, andmoney_put()is a locale facet operator (it uses the locale to format for money output operations). Usually you wouldn't call this directly (instead useput_money()). I actually had no idea C++ standard library (and most other languages) had built-in support for money values by locale, so this was a cool question for me!
- Location: Track A room, right side plant (near hallway to B)
Question: According to the C++23 standard, what is the guaranteed output of this program?
#include <iostream> struct E { E() { std::cout << "1"; } E(const E&) { std::cout << "2"; } ~E() { std::cout << "3"; } }; E f() { return E(); } int main() { f(); }
Answer: 13
Solution: Since C++17, when a prvalue of type
Tinitializes aTobject directly, the object is constructed in its final storage (copy elision is guaranteed). Hence, no copy/move constructors are called and2is never printed.1is printed at construction time and3is printed at the end off()inmainwhen theEobject is destroyed.
- Location: Alber Blanc sponsorship booth in lobby, drink on desk in top left
Question: According to the C++ standard, what is the guaranteed output of this program?
#include <iostream> #include <utility> class C { public: C(){} C(const C&){} // User-declared, disables move constructor }; int main() { C c; C c2(std::move(c)); std::cout << "ok"; }
Answer: ok
Solution: As the comment says, since a copy constructor is declared, the implicit move constructor isn't generated. But that's fine, because the
std::move(c)doesn't force a move by itself, it just castscto an rvalue. So theC c2(std::move(c))call uses the copy constructor, since a const lvalue can bind to an rvalue. Everything is fine and well and compiles.
- Location: Lobby, fourth stool to the right from the merch counter in the rightwards seating area
Question: According to the C++23 standard, what is the guaranteed output of this program?
#include <iostream> int main() { int a = 10; int b = 20; int x; x = a, b; std::cout << x; }
Answer: 10
Solution: The comma operator takes precedence over
=, so thex = a, b;expression statement parses as an assignment ofatox, and then an expression ofb. Soxis set to 10 and thenbis evaluated and discarded.
- Location: secret room, top right far corner, store door
Question: According to the C++23 standard, what is the output of this program?
#include <iostream> int main() { int I = 1, J = 1, K = 1; std::cout << (++I || ++J && ++K); std::cout << I << J << K; }
Answer: 1211
Solution: First
I, J, Kare all separately initialized to 1. Then the key thing to note is that&&takes precedence over||, so the logical expression is parsed as++I || (++J && ++K).++Iis evaluated first from the left and makesI = 2which is nonzero and truthy. That leads to short-circuiting, and(++J && ++K)is never touched. So 1 is printed as the boolean result, and the values ofI, J, Kare2, 1, 1respectively.
- Location: secret room, left wall near top, between two buildings
Question: According to the C++23 standard, what is the guaranteed output of this program?
#include <iostream> #include <map> using namespace std; int main() { map<bool,int> mb = {{1,2},{3,4},{5,0}}; cout << mb.size(); map<int,int> mi = {{1,2},{3,4},{5,0}}; cout << mi.size(); }
Answer: 13
Solution: In the map
mb, the keys1, 3, 5all convert totrue. But map keys are unique, so only one value remains fortrue(the0value), and the size of that map is 1.mifunctions as you'd expect -- all keys are different and map to those corresponding values. Somi's size is 3.
- Location: secret room, under a roof near bottom left side, only accessible from the north (Dutch meetup question)
Question: This program doesn't compile. If you could only insert one keyword, what could be used to fix the code?
#include <iostream> class MyClass { private: int x; public: MyClass(int val) : x(val) {} void setX(int val) const { x = val; } int getX() const { return x; } };
Answer: mutable
Solution: If we want to intentionally allow the
constfunctionsetXto mutatexwe need to markxasmutable. The reason we might want to use theconst/mutablepair here (as opposed to no qualifiers at all) is as a way to enforce defaulting toconst-correctness and usemutableonly for deliberate, narrow exceptions.
- Location: onboarding room, top right arrow
Question: According to the C++23 standard, what is the guaranteed output of this program?
#include <iostream> int main() { char* a = const_cast<char*>("Hello"); a[4] = '\0'; std::cout << a; }
Answer: UB
Solution: The string literal
"Hello"is stored in read-only memory on most systems. Theconst_cast<char*>only modifies the type. It doesn't actually make the underlying storage writable. Then trying to modify viaa[4] = '\0'might crash, appear to printHell, or do something else unpredictable. The safe way is to use a real writable arraychar a[] = "Hello";or to use astd::string.