Skip to content

Instantly share code, notes, and snippets.

@stellarpower
Created August 9, 2023 21:20
Show Gist options
  • Save stellarpower/f9458574b0df24b1a05518b7edb7ad2c to your computer and use it in GitHub Desktop.
Save stellarpower/f9458574b0df24b1a05518b7edb7ad2c to your computer and use it in GitHub Desktop.
Brace Initialisation with Custom Logic
// WIP
// For half-baked related ideas in a situation when this won't work or be acceptable, see:
//
// https://initialiser.godbolt.org/z/esqeYf98W
// https://initialiser.godbolt.org/z/hzqzfsarz
// https://initialiser.godbolt.org/z/a53ojboYd
// https://initialiser.godbolt.org/z/G3nExT9ba
//
struct Foo {
static constexpr unsigned ID = 0x33;
unsigned id;
const char *a;
int b;
float c;
// For when this would be annoying boilerplate to type
/*
Foo(const char *a, int b, float c)
: id(ID),
a(a), b(b), c(c)
{}
*/
};
template<class T>constexpr unsigned someBusinessLogic(){
return T::ID;
}
template<class T> struct Helper : public T{
template<class... Args> Helper(Args && ... args)
: T{someBusinessLogic<T>(), args...}
{}
// The secret is:
// - Relying on folding over the arguments
// - Being able ot put this into the brace-initialisation of the target type
// - Having a proxy type that can forward
// * (although maybe this can be reworked)
// * Without a second type the problem you can have is infinite recursion as the compiler now prefers the template ctor
// over brace-initialisation - which is what enables us to use that syntax aswell below in main.
};
int main(){
Helper<Foo> h1("hi", 9, 3.4f),
h2{"hi", 9, 3.4f}; // Also works using braces.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment