从模板化非类型模板参数推导模板参数
template parameter deduction from templated non-type template argument
我有以下类型定义:
template<typename G, typename T, typename R>
using my_func_type = typename R(T::*)(G, int) const;
这是一个我经常使用的成员函数,所以我正在尝试为它制作不同的包装器。前提是我想要一个通过公共函数调用实现这些功能的对象,这样我就可以用不同的方式组合它们(目前我使用直接的方式将调用包装为lambdas)。
但是,另一种方法是将该函数作为非类型模板参数传递(与 lambda 解决方案相比,这提高了我的性能,因为我一直在评估它),即
template<typename G, typename T, typename R, my_func_type<G, T, R> f>
struct MyWrapper
{
MyWrapper(G g, T t) : g{ g }, t{ t } {}
auto eval(int n) const
{
return (t.*f)(g, n);
}
protected:
G g;
T t;
};
int main()
{
AnObject g;
TheCallingObject t;
auto f = &TheCallingObject::callit;
MyWrapper<AnObject, TheCallingObject, double, f> wrap(g, t)
}
但这似乎有点多余,那么模板参数是否可以从f
推导出来?
我找到的中途解决方案是:
template<auto f, typename G, typename T>
struct MyWrapper
{
OpFuncDerivative(G g, T t) : g{ g }, t{ t } {}
auto eval(int n) const
{
return (t.*f)(g, n);
}
protected:
G g;
T t;
};
int main()
{
AnObject g;
TheCallingObject t;
auto f = &TheCallingObject::callit;
// it won't automatically deduce AnObject and TheCallingObject
// through the parameters to the constructor though!
MyWrapper<f, AnObject, TheCallingObject> wrap(g, t)
}
你可以写一个辅助函数:
template<typename G, typename T, auto f>
struct MyWrapper
{
MyWrapper(G g, T t) : g{g}, t{t}
{}
auto eval(int n) const
{
return (t.*f)(g, n);
}
protected:
G g;
T t;
};
template<auto f, typename G, typename T>
MyWrapper<G, T, f> make_wrapper(G g, T t)
{
return {g, t};
}
然后像这样使用它:
int main()
{
AnObject g;
TheCallingObject t;
constexpr auto f = &TheCallingObject::callit;
auto wrap = make_wrapper<f>(g, t);
}
我有以下类型定义:
template<typename G, typename T, typename R>
using my_func_type = typename R(T::*)(G, int) const;
这是一个我经常使用的成员函数,所以我正在尝试为它制作不同的包装器。前提是我想要一个通过公共函数调用实现这些功能的对象,这样我就可以用不同的方式组合它们(目前我使用直接的方式将调用包装为lambdas)。
但是,另一种方法是将该函数作为非类型模板参数传递(与 lambda 解决方案相比,这提高了我的性能,因为我一直在评估它),即
template<typename G, typename T, typename R, my_func_type<G, T, R> f>
struct MyWrapper
{
MyWrapper(G g, T t) : g{ g }, t{ t } {}
auto eval(int n) const
{
return (t.*f)(g, n);
}
protected:
G g;
T t;
};
int main()
{
AnObject g;
TheCallingObject t;
auto f = &TheCallingObject::callit;
MyWrapper<AnObject, TheCallingObject, double, f> wrap(g, t)
}
但这似乎有点多余,那么模板参数是否可以从f
推导出来?
我找到的中途解决方案是:
template<auto f, typename G, typename T>
struct MyWrapper
{
OpFuncDerivative(G g, T t) : g{ g }, t{ t } {}
auto eval(int n) const
{
return (t.*f)(g, n);
}
protected:
G g;
T t;
};
int main()
{
AnObject g;
TheCallingObject t;
auto f = &TheCallingObject::callit;
// it won't automatically deduce AnObject and TheCallingObject
// through the parameters to the constructor though!
MyWrapper<f, AnObject, TheCallingObject> wrap(g, t)
}
你可以写一个辅助函数:
template<typename G, typename T, auto f>
struct MyWrapper
{
MyWrapper(G g, T t) : g{g}, t{t}
{}
auto eval(int n) const
{
return (t.*f)(g, n);
}
protected:
G g;
T t;
};
template<auto f, typename G, typename T>
MyWrapper<G, T, f> make_wrapper(G g, T t)
{
return {g, t};
}
然后像这样使用它:
int main()
{
AnObject g;
TheCallingObject t;
constexpr auto f = &TheCallingObject::callit;
auto wrap = make_wrapper<f>(g, t);
}