在这里,我有以下类型的仿函数:
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()`
}
};
Run Code Online (Sandbox Code Playgroud)
和示例结构:
struct FF
{
int m;
int r;
};
Run Code Online (Sandbox Code Playgroud)
我想使用仿函数X,但我不想显式指定模板参数,如下所示:
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?
}
Run Code Online (Sandbox Code Playgroud)
在这里我尝试了没有成功:
// 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>();
}
Run Code Online (Sandbox Code Playgroud)
我只是不会将成员指针存储为模板参数:
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;
}
Run Code Online (Sandbox Code Playgroud)
我不认为用你的方法推断类型是不可能的:你不能使用指向成员的指针传递给发生类型推导的函数.
编辑: 可能有基于宏的解决方案.
例如,您可以创建一个类来创建X实例,如下所示:
template <class T, class Foo>
struct XMaker
{
template <T Foo::*p>
X<T, Foo, p> make() { return X<T, Foo, p>(); }
};
Run Code Online (Sandbox Code Playgroud)
现在,您可以创建一个make ...函数来推导T和Foo:
template <class T, class Foo>
XMaker<T, Foo> make_x_maker(T Foo::*)
{
return XMaker<T, Foo>();
}
Run Code Online (Sandbox Code Playgroud)
这使得编写一个宏成为可能:
#define CREATE_X(member) make_x_maker(member).make<member>()
Run Code Online (Sandbox Code Playgroud)
用法:
std::for_each(cont.begin(), cont.end(), CREATE_X(&FF::r) );
Run Code Online (Sandbox Code Playgroud)