Skip to content

Instantly share code, notes, and snippets.

@Nekrolm
Created May 31, 2025 19:04
Show Gist options
  • Save Nekrolm/56c0b7843a6bd129ae6dd176716b228a to your computer and use it in GitHub Desktop.
Save Nekrolm/56c0b7843a6bd129ae6dd176716b228a to your computer and use it in GitHub Desktop.
How to ban ALL implicit argument conversions for the function
#include <concepts>
#include <functional>
template <class... Args>
constexpr inline auto make_safe = [](std::invocable<Args...> auto&& caller) {
return [f = std::forward<decltype(caller)>(caller)](std::same_as<Args> auto&&... args) -> decltype(auto) {
return std::invoke(f, std::forward<Args>(args)...);
};
};
template <class F>
struct SafeCallerSelector;
template <class R, class... Args>
struct SafeCallerSelector<R(*)(Args...)> {
constexpr static inline auto safe = make_safe<Args...>;
};
template <class C, class R, class... Args>
struct SafeCallerSelector<R (C::*)(Args...) const> {
constexpr static inline auto safe = make_safe<Args...>;
};
template <class F>
struct SafeCallerSelector: SafeCallerSelector<decltype(&F::operator())> {};
template <class F>
auto safe(F&& callable) {
static constexpr auto safe_maker = SafeCallerSelector<std::decay_t<F>>::safe;
return safe_maker(std::forward<F>(callable));
}
#include <vector>
#include <utility>
auto SumV = safe([](std::vector<int> v){
int sum = 0;
for (auto x: v) { sum += x; }
return sum;
});
int main(int argc, const char* argv[]) {
std::vector<int> v = {1,2,3,4,5};
SumV(v); // implicity copy? Compilation Error!
SumV(auto(v)); // copy explicitly, nice!
SumV(std::move(v)); // or move explicitly, nice!
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment