How to reduce template arguments?
c++, templates
Solution
I just wouldn't store the member pointer as a template argument:
template<class T, class Foo>
struct X {
X(T Foo::*p): p(p) {}
void operator()(Foo & f) {
(f.*p) = 12 * (f.*p); // simple example. could be more complex `operator()`
}
private:
T Foo::*p;
};
template <class T, class Foo>
X<T, Foo> MakeX(T Foo::*p)
{
return p;
}
I don't think it is possible to deduce the types with your approach: you can't use a pointer-to-member passed to a function which is where the type deduction occurs.
Edit: There may be macro-based solutions, though.
For example, you can make a class to create X instances, like this:
template <class T, class Foo>
struct XMaker
{
template <T Foo::*p>
X<T, Foo, p> make() { return X<T, Foo, p>(); }
};
Now, you can create a make... function to deduce T and Foo:
template <class T, class Foo>
XMaker<T, Foo> make_x_maker(T Foo::*)
{
return XMaker<T, Foo>();
}
Which makes it possible to write a macro like:
#define CREATE_X(member) make_x_maker(member).make<member>()
Usage:
std::for_each(cont.begin(), cont.end(), CREATE_X(&FF::r) );
Problem
Here I have functor of the follow kind: ``` template<class T, class Foo, T Foo::*p> struct X { void operator()(Foo & f) { (f.*p) = 12 * (f.*p); // simple example. could be more complex `operator()` } }; ``` And sample struct: ``` struct FF { int m; int r; }; ``` I want to use the functor X, but I don't want to explicitly specify template argument as follows: ``` void testforx() { std::vector<FF> cont(5); std::for_each(cont.begin(), cont.end(), X<int, FF, &FF::r>() ); // it work, but I don't want to write `int` and `FF` std::for_each(cont.begin(), cont.end(), createx<&FF::r>() ); // how I would like to use it, how to declare `createx` function? } ``` Here what I tried with no success: ``` // that is what I tried, but it could not deduce T and Foo template<T Foo::*p, class T, class Foo> X<T, Foo, T Foo::*p> createx() { return X<T, Foo, p>(); } // this works, but requires to write T and Foo explicitly template<class T, class Foo, T Foo::*p> X<T, Foo, T Foo::*p> createx() { return X<T, Foo, p>(); } ```