Skip to content

Instantly share code, notes, and snippets.

@vladiant
Last active May 2, 2026 17:55
Show Gist options
  • Select an option

  • Save vladiant/b3d676f8edc6a8cd4011c1eb29edb02f to your computer and use it in GitHub Desktop.

Select an option

Save vladiant/b3d676f8edc6a8cd4011c1eb29edb02f to your computer and use it in GitHub Desktop.
The Global API Injection Pattern
// https://www.elbeno.com/blog/?p=1831
// https://medium.com/@abhishek.kr121/variadic-templates-in-c-6955933f5781
#include <iostream>
// Initial code
// auto log() -> void { std::cout << std::endl; }
// template <typename T, typename... Args>
// auto log(const T& arg, Args... args) -> void {
// std::cout << arg << " ";
// log(std::forward<Args>(args)...);
// std::cout << std::endl;
// }
// Logger implementation
struct logger {
static auto print() -> void { std::cout << std::endl; }
template <typename T, typename... Args>
static auto print(const T& arg, Args... args) -> void {
std::cout << arg << " ";
print(std::forward<Args>(args)...);
std::cout << std::endl;
}
template <typename... Args>
static auto log(Args... args) -> void {
std::cout << "logger: ";
print(std::forward<Args>(args)...);
std::cout << std::endl;
}
};
// Interface
template <typename...>
constexpr static auto log_api = logger{};
template <typename... DummyArgs, typename... Args>
auto log(Args&&... args) -> void {
auto& api = log_api<DummyArgs...>;
api.log(std::forward<Args>(args)...);
}
// Local impelementation
struct Tag {};
template <>
constexpr auto log_api<Tag> = logger{};
int main() {
// log("Hello", "C++", 14);
log<Tag>("Hello", "C++", 14);
return 0;
}
// https://www.elbeno.com/blog/?p=1831
// https://medium.com/@abhishek.kr121/variadic-templates-in-c-6955933f5781
#include <iostream>
// Initial code
// template <typename... Args>
// auto log(Args&&... args) -> void {
// ((std::cout << args << " "), ...) << std::endl;
// }
// Logger implementation
struct logger {
template <typename... Args>
static auto log(Args&&... args) -> void {
std::cout << "logger: ";
((std::cout << args << " "), ...) << std::endl;
}
};
// Interface
template <typename...>
constexpr inline auto log_api = logger{};
template <typename... DummyArgs, typename... Args>
auto log(Args&&... args) -> void {
auto& api = log_api<DummyArgs...>;
api.log(std::forward<Args>(args)...);
}
// Local impelementation
struct Tag {};
template <>
constexpr inline auto log_api<Tag> = logger{};
int main() {
// log("Hello", "C++", 17);
log<Tag>("Hello", "C++", 17);
return 0;
}
// https://www.elbeno.com/blog/?p=1831
#include <print>
// Initial code
// auto log(auto&&... args) -> void {
// std::print("logger: {2} {1}{0}!\n", args...);
// }
// Logger implementation
struct logger {
static auto log(auto&&... args) -> void {
std::print("logger: {2} {1}{0}!\n", args...);
}
};
// Interface
template <typename...>
constexpr inline auto log_api = logger{};
template <typename... DummyArgs, typename... Args>
auto log(Args&&... args) -> void {
auto& api = log_api<DummyArgs...>;
api.log(std::forward<Args>(args)...);
}
// Local impelementation
struct Tag {};
template <>
constexpr inline auto log_api<Tag> = logger{};
int main() {
// std::print("{2} {1}{0}!\n", 23, "C++", "Hello");
// log(23, "C++", "Hello");
log<Tag>(23, "C++", "Hello");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment