C++ std::使用可变模板、绑定参数和占位符绑定

C++ std::使用可变模板、绑定参数和占位符绑定,c++,c++11,variadic-templates,stdbind,C++,C++11,Variadic Templates,Stdbind,我正在编写一些代码,这些代码要求我能够使用std::bind绑定函数,可能会绑定一些参数,并保留一些参数作为占位符 我有一门课: template <typename return_t,typename... args_t> class signal_base<return_t(args_t...)> { using slot_t = std::function<return_t(args_t...)>; using slot_id_t = s

我正在编写一些代码,这些代码要求我能够使用
std::bind
绑定函数,可能会绑定一些参数,并保留一些参数作为占位符

我有一门课:

template <typename return_t,typename... args_t>
class signal_base<return_t(args_t...)>
{
    using slot_t = std::function<return_t(args_t...)>;
    using slot_id_t = std::size_t;
    /*other members...*/

    slot_id_t connect(slot_t const& slot)
    {
        slot_id_t out;
        {
            std::unique_lock<std::mutex> lk{_slots_mtx};
            _slots.emplace(_current_id,slot);
            out = _current_id++;
        }
        return out;
    }

    template<typename F, typename... a_t, std::size_t... I>
    slot_id_t attach(F&& f, a_t&&... args, index_sequence<I...> seq)
    {
        return connect(std::bind(&f,std::ref(args)..., placeholder_template<I>{}...));
    }
    template<typename F, typename... a_t>
    slot_id_t attach(F&& f, a_t&&... args)
    {
        return attach(std::forward<F&&>(f),std::forward<a_t&&>(args)..., make_index_sequence<sizeof...(args_t)>{});
    }
};
我的同事是:

Apple LLVM version 8.0.0 (clang-800.0.42.1)
我也尝试过GCC6.3,但它刚刚卡住了

我的主要意见是:

struct example
{
    double data;

    static void boop(example& e, const double&v,int)
    {
        std::cout<<"boop";
    }
};

int main(int argc, char** argv)
{
    example e; //instance of the example
    signals::signal_t<void(const double&,int)> sig; //signal class that will call all attached listeners on emit()

    sig.attach(&example::boop,e); //attach example::boop with the first argument e, leaving the last two arguments as placeholders
    double d =0.0;
    sig.emit(d,0);//call with double and int
    return 0;
}
为什么
使索引序列
似乎扩展了很多倍,以至于超过了递归模板的深度?在该函数中,
sizeof…(args_2)==2时:

template<typename F, typename... a_t, std::size_t... I>
slot_id_t attach(F&& f, a_t&&... args, index_sequence<I...> seq);
模板
插槽id附加(F&&F、a&&…参数、索引顺序顺序);
a_t
是非推断上下文,因为它是一个参数包,不是最后一个参数。结果,演绎失败,你的函数无法被调用——所以你只是永远递归地调用自己,每次都附加相同的参数

相反,颠倒顺序。将
索引\u序列
作为第一个参数

在此函数中:

template<typename F, typename... a_t, std::size_t... I>
slot_id_t attach(F&& f, a_t&&... args, index_sequence<I...> seq);
模板
插槽id附加(F&&F、a&&…参数、索引顺序顺序);
a_t
是非推断上下文,因为它是一个参数包,不是最后一个参数。结果,演绎失败,你的函数无法被调用——所以你只是永远递归地调用自己,每次都附加相同的参数


相反,颠倒顺序。将
索引\u序列
作为第一个参数

这显然不能回答您的问题(这就是为什么它是注释),但不要使用
std::bind
。就用一个兰姆达吧,弗里德曼,这可能是我不得不求助的,但在经历了这么多麻烦之后。。。我真的很想知道问题是什么。这显然不能回答你的问题(这就是为什么它是注释),但不要使用
std::bind
。就用一个兰姆达吧,弗里德曼,这可能是我不得不求助的,但在经历了这么多麻烦之后。。。我真的很想知道问题是什么,那会是什么样子?您的意思是将move
std::size\u t…I
作为第一个模板参数,还是将move
index\u sequence seq
作为第一个函数参数?你能发布一段修改后的签名吗?@AlexZywicki First函数参数-你需要最后一个参数包。那会是什么样子?您的意思是将move
std::size\u t…I
作为第一个模板参数,还是将move
index\u sequence seq
作为第一个函数参数?你能发布一段修改后的签名吗?@AlexZywicki First函数参数-你需要最后一个参数包。
template<typename F, typename... a_t, std::size_t... I>
slot_id_t attach(F&& f, a_t&&... args, index_sequence<I...> seq);