【问题标题】:c++ how to combine std::bind and variadic tuples?c ++如何结合std :: bind和可变元组?
【发布时间】:2020-06-18 18:07:50
【问题描述】:

相关帖子:How to combine std::bind(), variadic templates, and perfect forwarding?

有没有办法将函数与可变元组绑定?这里指示意图的代码不正确:

// t is an instance of T
auto f = std::bind(&T::iterate,t,???);
// args is an instance of std::tuple<Args...> args;
std::apply(f,args);

(注意:我不确定“可变元组”是否是正确的术语。期待您的更正编辑帖子)

【问题讨论】:

  • 请看看如何制作minimal reproducible example。您是否有权访问要使用绑定的范围内的Args... 包?
  • 另外,不要使用std::bind,使用 lambdas。

标签: c++ templates bind variadic-functions


【解决方案1】:

不要使用bind,而是使用 lambda:

auto f = [&t](auto... args){ t.iterate(args...); };
std::apply(f, args);

如果你想要完美的转发,那看起来像:

auto f = [&t](auto&&... args){ t.iterate(std::forward<decltype(args)>(args)...); };
std::apply(f, args);

【讨论】:

    【解决方案2】:

    从 C++20 开始你可以使用std::bind_front:

    template<class T>
    void print (T val) {
        std::cout << val << std::endl;
    }
    
    struct T {
        template<class ... Args>
        void iterate(Args... args) {
            int temp[] = { (print(args),0)... };
        }
    };
    
    // all happens here
    template<class ... Args>
    void foo(const tuple<Args...>& args) {
        T t;
        auto f = std::bind_front(&T::iterate<Args...>,&t);
        std::apply(f,args);
    }
    
    // the call 
    int i = 1;
    foo(std::make_tuple(i,i+1,"bind is cool"));
    

    如果你想使用旧的std::bind,你可以提供你自己的占位符来从包中生成:

    template<int N>
    struct MyPlaceholder {};
    
    namespace std {
        template<int N>
        struct is_placeholder<MyPlaceholder<N>> : public integral_constant<int, N> {};
    }
    
    template<class ... Args, size_t ... Indices>
    void foo2helper(const tuple<Args...>& args, std::index_sequence<Indices...>) {
        T t;
        auto f = std::bind(&T::iterate<Args...>,&t, (MyPlaceholder<Indices+1>{})...);
        std::apply(f,args);
    }
    
    template<class ... Args>
    void foo2(const tuple<Args...>& args) {
        foo2helper(args, std::make_index_sequence<sizeof...(Args)>{});
    }
    // the call
    foo2(std::make_tuple(2.34,"only bind"));
    

    Live demo

    【讨论】:

      猜你喜欢
      • 2012-10-27
      • 2013-08-25
      • 1970-01-01
      • 1970-01-01
      • 2017-03-24
      • 1970-01-01
      • 1970-01-01
      • 2019-04-30
      • 2012-05-20
      相关资源
      最近更新 更多