#include #include #include #include #include void loc(std::source_location l = std::source_location::current()) { std::cout << l.file_name() << ':' << l.line() << ' ' << l.function_name() << "\n"; } void function() { loc(); } auto lambda = [] { loc(); }; struct functor_type { void operator()() { loc(); } }; struct struct_type { void method() { loc(); } }; template decltype(auto) apply_test(Callable &&c, Args &&...args) { std::decay_t callable = std::forward(c); std::tuple arguments = {std::forward(args)...}; return std::apply(callable, arguments); } template decltype(auto) function_test(Callable &&c, Args &&...args) { using result_type = std::invoke_result_t; std::function function = std::forward(c); return function(std::forward(args)...); } template std::invoke_result_t invoke_test(Callable &&c, Args &&...args) { return std::invoke(std::forward(c), std::forward(args)...); } template void test_by_code(Callable &&c, Args &&...args) { asm volatile("mfence" : : : "memory"); apply_test(c, args...); asm volatile("mfence" : : : "memory"); function_test(c, args...); asm volatile("mfence" : : : "memory"); invoke_test(c, args...); asm volatile("mfence" : : : "memory"); } int main() { test_by_code(function); test_by_code(lambda); test_by_code(functor_type{}); test_by_code(&struct_type::method, struct_type{}); }