I am trying to create a wrapper function that has the exact same interface as the function that it wraps, with zero runtime cost overhead.
In the example code below, is it possible to design my_function_wrapped in a way so that it has the same interface as my_function, so that calling it with the exact same arguments as to my_function always yield the same results?
#include <iostream>
using namespace std;
struct SMyStruct
{
SMyStruct() { cout << "SMyStruct constructed" << std::endl;}
SMyStruct(SMyStruct&& Other) { cout << "SMyStruct moved" << std::endl;}
SMyStruct(const SMyStruct& Other) { cout << "SMyStruct copied" << std::endl; }
~SMyStruct() {cout << "SMyStruct destroyed" << std::endl;}
};
void my_function(SMyStruct Arg)
{
}
template<typename T>
void my_function_wrapped(T&& Arg)
{
my_function(std::forward<T>(Arg));
// Some extra logic here that doesn't use Arg
}
int main()
{
cout << "-----------------------------" << endl;
cout << "Direct call to my_function:" << endl;
cout << "-----------------------------" << endl;
my_function(SMyStruct());
cout << "-----------------------------" << endl;
cout << "Wrapped call to my_function:" << endl;
cout << "-----------------------------" << endl;
my_function_wrapped(SMyStruct());
return 0;
}
This program outputs:
-----------------------------
Direct call to my_function:
-----------------------------
SMyStruct constructed
SMyStruct destroyed
-----------------------------
Wrapped call to my_function:
-----------------------------
SMyStruct constructed
SMyStruct moved
SMyStruct destroyed
SMyStruct destroyed
I realize that copy/move is elided on the first call to my_function because SMyStruct() is a prvalue. Is it possible to wrap this call in my_function_wrapped and still get the elided copy/move? Is there any zero-cost way to abstract away the call?
godbolt-link to the code: https://godbolt.org/z/joGTTe64f
Thanks!