Home > OS >  Using template type as argument to std::invoke
Using template type as argument to std::invoke

Time:09-01

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);

Demo

  • Related