可变参数模板和std :: bind [英] Variadic templates and std::bind

查看:137
本文介绍了可变参数模板和std :: bind的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于以下模板化函数,如何更改它以利用可变参数模板?也就是说,要用可变参数代替std :: bind占位符而不是P1和P2?目前,我对每个Arity拥有这些功能之一,其中Arity零没有P参数,直到Arity 9具有P1到P9参数。我希望尽可能将其折叠为一个函数。

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? 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. 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));
}


推荐答案

您可以(部分)专业化 std :: is_placeholder 用于自定义模板的特殊化。这样,您可以通过常用的 int_sequence 技术引入占位符生成器。

You can (partially) specialize std::is_placeholder for specializations of a custom template. This way, you can introduce a placeholder generator via the usual int_sequence technique.

来自[func.bind.isplace ] / 2

From [func.bind.isplace]/2


实现应提供一个定义,该定义的 BaseCharacteristic integral_constant< int,J>
如果 T std的类型::占位符:: _ J ,否则它的 BaseCharacteristic integral_constant< int,0> 。程序可能会将模板专门用于用户定义的类型 T ,以使其 BaseCharacteristic integer_constant< int,N> N> 0 表示应将 T 视为占位符类型。

The implementation shall provide a definition that has the BaseCharacteristic of integral_constant<int, J> if T is the type of std::placeholders::_J, otherwise it shall have a BaseCharacteristic of integral_constant<int, 0>. A program may specialize this template for a user-defined type T to have a BaseCharacteristic of integral_constant<int, N> with N > 0 to indicate that T should be treated as a placeholder type.

通常的 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...> {};

自定义占位符模板和 is_placeholder 的特化:

The custom placeholder template and specialization of 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
    {};
}

我不确定在哪里引入 1 ;

I'm not sure where to introduce the 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) >{});
}

活页夹的用法示例:

#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);
}

这篇关于可变参数模板和std :: bind的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆