Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a pointer-to-class-member as a template parameter

Tags:

c++

templates

I would like to write a function that apply a process to member of a class. The following code is working:

class AA
{
public:
    AA(){};
    ~AA(){};
    std::string type="AA";
};

class BB
{
public:
    BB(){};
    ~BB(){};
    template <typename T, typename TT>
    void test(T& a, TT(T::*memberPtr))
    {
        std::cout<<"test: "<<(a.*memberPtr)<<std::endl;
    }
    std::string type="BB";
};

int main()
{
    AA a;
    BB b;
    b.test(a, &AA::type);
}

But I know everything at compile-time so I am wondering if it is possible to write something equivalent but only with templates? So I could write something like:

b.test<&AA::type>(a);

that calls inside test(a):

std::cout<<"test: "<< (a.*MEMBER) <<std::endl; // MEMBER is given in template

or something like that.

like image 753
StormRider Avatar asked Jan 08 '23 17:01

StormRider


1 Answers

You can't do just test<&AA::type>, since you'd need to also tell the function template what type of pointer-to-member you're expecting. The typical pattern is:

template <class M, M member, class T> // deduced go last
void test(T& a) {
    cout << (a.*member);
}

With usage:

test<decltype(&AA::type), &AA::type>

I believe there's currently a proposal to reduce the verbosity there, but until then, it's not the worst thing in the world, and you could always:

#define TYPE_AND_VAL(foo) decltype(foo), foo
test<TYPE_AND_VAL(&AA::type)>

That proposal I mentioned is in C++17, and will allow you to do:

template <auto member, class T>
void test(T& a) {
    cout << (a.*member);
}

test<&AA::type>(a);
like image 186
Barry Avatar answered Jan 17 '23 14:01

Barry