Consider this code:
using namespace std;
struct FS
{
void print() { cout << "p\n"; }
int s;
};
template <typename T, typename F>
void myInvoke(T& t, F f)
{
invoke(f, t) = 10;
}
int main(int, char**)
{
FS fs;
myInvoke(fs, &FS::s);
cout << fs.s << "\n";
}
Is there anyway to avoid the runtime cost of passing the class member pointer to myInvoke?
I can of course do:
template <typename T>
void myInvoke(T& t)
{
invoke(&T::s, t) = 10;
}
// then call with
myInvoke(fs);
What I'd like to do:
template <typename T, typename P, P FS::* f>
void myInvoke(T& t)
{
invoke(f, t) = 30;
}
// call with:
myInvoke<FS, int ,&FS::s>(fs);
But without the typename P. Is there any way to make the call more concise so it can be called with:
myInvoke<FS, &FS::s>(fs);
I know this is a bit arcane, but it'd be really nice to be as concise as possible. Especially when you have widely used library functions.
EDIT: Link to sandbox above code: https://godbolt.org/z/z4cGdPd3r
CodePudding user response:
It seems you are looking for deduced Non-type template parameter (with auto
) (C 17):
template <auto F, typename T>
void myInvoke(T& t)
{
invoke(F, t) = 10;
}
with usage:
myInvoke<&FS::s>(fs);