[英]Variadic templates and std::bind
Given the following templated function, how can I change it to take advantage of variadic templates?鉴于以下模板化函数,我如何更改它以利用可变参数模板? That is to say, to replace std::bind placeholders with a variadic parameter instead of P1 and P2?也就是说,用可变参数代替 P1 和 P2 替换 std::bind 占位符? At the moment I have one of these functions per arity, with arity zero having no P parameter, up to arity 9 having P1 to P9 parameters.目前我每个元都有这些函数之一,元零没有 P 参数,最高元 9 有 P1 到 P9 参数。 I was hoping to collapse this into a single function if possible.如果可能的话,我希望将其折叠为一个函数。
template<typename R, typename T, typename U, typename P1, typename P2>
void Attach(R (T::*f)(P1, P2), U p)
{
AttachInternal(p, std::bind(f,
p.get(),
std::placeholders::_1,
std::placeholders::_2));
}
You can (partially) specialize std::is_placeholder
for specializations of a custom template.您可以(部分)特化std::is_placeholder
以实现自定义模板的特化。 This way, you can introduce a placeholder generator via the usual int_sequence
technique.这样,您可以通过通常的int_sequence
技术引入占位符生成器。
From [func.bind.isplace]/2来自 [func.bind.isplace]/2
The implementation shall provide a definition that has the
BaseCharacteristic
ofintegral_constant<int, J>
ifT
is the type ofstd::placeholders::_J
, otherwise it shall have aBaseCharacteristic
ofintegral_constant<int, 0>
.如果T
是std::placeholders::_J
的类型,则实现应提供具有BaseCharacteristic
integral_constant<int, J>
的BaseCharacteristic
的定义,否则它应具有BaseCharacteristic
integral_constant<int, 0>
的BaseCharacteristic
。 A program may specialize this template for a user-defined typeT
to have aBaseCharacteristic
ofintegral_constant<int, N>
withN > 0
to indicate thatT
should be treated as a placeholder type.程序可以为用户定义的类型T
此模板,使其具有BaseCharacteristic
integral_constant<int, N>
的BaseCharacteristic
,其中N > 0
以指示T
应被视为占位符类型。
The usual int_sequence
:通常的int_sequence
:
#include <cstddef>
template<int...> struct int_sequence {};
template<int N, int... Is> struct make_int_sequence
: make_int_sequence<N-1, N-1, Is...> {};
template<int... Is> struct make_int_sequence<0, Is...>
: int_sequence<Is...> {};
The custom placeholder template and specialization of is_placeholder
: is_placeholder
的自定义占位符模板和专业化:
template<int> // begin with 0 here!
struct placeholder_template
{};
#include <functional>
#include <type_traits>
namespace std
{
template<int N>
struct is_placeholder< placeholder_template<N> >
: integral_constant<int, N+1> // the one is important
{};
}
I'm not sure where to introduce the 1
;我不确定在哪里介绍1
; the places I considered are all not optimal.我考虑的地方都不是最佳的。
Using it to write some binder:用它来写一些活页夹:
template<class Ret, class... Args, int... Is>
void my_bind(Ret (*p)(Args...), int_sequence<Is...>)
{
auto x = std::bind(p, placeholder_template<Is>{}...);
x( Args(42)... );
}
template<class Ret, class... Args>
void my_bind(Ret (*p)(Args...))
{
my_bind(p, make_int_sequence< sizeof...(Args) >{});
}
Usage example of the binder:活页夹的使用示例:
#include <iostream>
void foo(double, char, int) { std::cout << __PRETTY_FUNCTION__ << "\n"; }
void bar(bool, short) { std::cout << __PRETTY_FUNCTION__ << "\n"; }
int main()
{
my_bind(foo);
my_bind(bar);
}
I would like to propose a more simple solution to the problem to bind a member function to a variable number of placeholders:我想提出一个更简单的解决方案来将成员函数绑定到可变数量的占位符:
template<typename R, typename T, typename U, typename... Args>
std::function<R(Args...)> Attach(R (T::*f)(Args...), U p)
{
return [p,f](Args... args)->R { return (p->*f)(args...); };
};
A simple example of the usage looks like that一个简单的用法示例如下所示
class CrazyAdd
{
public:
CrazyAdd(double val)
: m_crazyPart(val)
{}
double add(double a, double b)
{
return a+b+m_crazyPart;
}
private:
double m_crazyPart;
};
void main() {
CrazyAdd myAdd(39);
// Create a function object that is bound to myAdd
auto f = Attach(&CrazyAdd::add, &myAdd);
// Call the function with the parameters
std::cout << f(1,2) << std::endl; // outputs 42
}
Personally I think that's another good example why Scott Meyer recommends lambdas instead of std::bind.我个人认为这是 Scott Meyer 推荐 lambdas 而不是 std::bind 的另一个很好的例子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.