Last active
August 2, 2023 17:34
-
-
Save stellarpower/9d2bcaeb89e3f78adae037a73048e775 to your computer and use it in GitHub Desktop.
Use of a private struct to jimmy in arbitrary code before the submember initialisation of a class. we don't even need operator comma!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Inherit from me privately. | |
struct ConstructorPreInitialisation{ | |
// Pass in an arbitrary lambda function here, it will simply be discarded | |
// This remoes the need for a comma operator and importantly avoids cluttering your | |
// real initialisation of member subobjects. | |
inline ConstructorPreInitialisation( [[maybe_unused]] const auto λ ){ λ(); } | |
}; | |
// WARN: This may increase the size of your class using it | |
// The compiler can probably elide this but from memory objects with zero length are not permitted | |
// Have not checked the fine details against the standard | |
// Therefore this should not be used if this is an unacceptable condition | |
// Usage | |
// Example class originally from: https://en.cppreference.com/w/cpp/language/constructor#Example | |
#include <fstream> | |
#include <string> | |
#include <mutex> | |
struct Base | |
{ | |
int n; | |
}; | |
struct Class : public Base, private ConstructorPreInitialisation | |
{ | |
unsigned char x; | |
unsigned char y; | |
std::mutex m; | |
std::lock_guard<std::mutex> lg; | |
std::fstream f; | |
std::string s; | |
Class(int x) | |
: Base{123}, // initialize base class | |
ConstructorPreInitialisation([&](){ | |
// Call some global allocation here, for example. | |
}), | |
x(x), // x (member) is initialized with x (parameter) | |
y{0}, // y initialized to 0 | |
f{"test.cc", std::ios::app}, // this takes place after m and lg are initialized | |
s(__func__), // __func__ is available because init-list is a part of constructor | |
lg(m), // lg uses m, which is already initialized | |
m{} // m is initialized before lg even though it appears last here | |
{} // empty compound statement | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment