#include <iostream>
#include <utility>
#include <type_traits>
using namespace std;
int LastError() { return 0; }
struct Error {
Error(int err, const char*, int) {}
};
template<typename R, typename... Args>
inline auto Check(R (&call)(Args...), Args... args)
{
if constexpr (!is_void_v<R>)
{
R ret = call(args...);
int err = LastError();
if (err != 0) throw Error(err, __FILE__, __LINE__);
return ret;
}
else
{
call(args...);
int err = LastError();
if (err != 0) throw Error(err, __FILE__, __LINE__);
}
}
void ExternalFct1(int, int, int)
{
cout << "ExternalFct1" << endl;
}
int ExternalFct2(int, int, int)
{
cout << "ExternalFct2" << endl;
return 0;
}
int main()
{
Check(ExternalFct1, 1, 2, 3);
return Check(ExternalFct2, 1, 2, 3);
}