tools
tools copied to clipboard
Add strict_invoke
https://compiler-explorer.com/z/W33rTKzKG
#include <type_traits>
#include <functional>
template <typename Ret, typename... Arg, typename... Param>
constexpr auto strict_invoke(Ret (*f)(Arg...),
Param&&... param) noexcept(false) -> Ret
requires(
std::is_same_v<std::remove_cvref_t<Arg>, std::remove_cvref_t<Param>> &&
...)
&& std::is_invocable_v<decltype(f), decltype(param)...>
{
return f(std::forward<Param>(param)...);
}
double add(double lhs, double rhs) {
return lhs + rhs;
}
int main()
{
add(2.3f, 1.3f); // works
add(2, 1); // works
//strict_invoke(&add, 2.3f, 1.3f); // fails, requires conversion
strict_invoke(&add, 1.3, 1.3); // works
//strict_invoke(&add, 1, 2); // fails, requires conversion
}