调用成员函数扩展元组parms std :: invoke vs std :: apply

Kla*_*aus 2 c++ tuples c++17

我发现std::invoke用一组参数调用每个可调用对象,并将std::apply一个元组作为参数扩展为可调用.

是否有两者的组合能够调用任何可调用的元组作为参数?

#include <iostream>
#include <tuple>
#include <functional>

class A
{
    private:
        int n;

    public:
        A( int _n ): n(_n){}

        void operator()(int x, double y )
        {
            std::cout << n << " " << x << " " << y << std::endl;
        }

        void MemFun( int x, double y )
        {
            std::cout << n << " " << x << " " << y << std::endl;
        }
};

int main()
{
    A a(100);
    std::invoke( a, 10, 1.23 );

    auto parm2 = std::make_tuple( 1,2.34);
    std::apply ( a, parm2 );

    std::invoke ( &A::MemFun, a, 4, 5.67 );

    // ???
    std::??apply_invoke?? ( &A::MemFun, a, parm2 );
}
Run Code Online (Sandbox Code Playgroud)

Rak*_*111 12

你的意思是这样的吗?

std::apply(&A::MemFun, std::tuple_cat(std::make_tuple(a), parm2));
Run Code Online (Sandbox Code Playgroud)

是否有两者的组合能够调用任何可调用的元组作为参数?

std::apply可以用来调用任何可调用的,所以我不是真正理解这里的问题.它就像std::invoke成员函数一样:第一个参数需要是你想要调用函数的对象.同样如此std::apply,传递的元组的第一个元素需要是您希望它被调用的对象.

如果你不喜欢指定std::tuple_cat等等,你总是可以创建一个包装器:

template<typename F, typename T, typename U>
decltype(auto) apply_invoke(F&& func, T&& first, U&& tuple) {
    return std::apply(std::forward<F>(func), std::tuple_cat(std::forward_as_tuple(std::forward<T>(first)), std::forward<U>(tuple)));
}
Run Code Online (Sandbox Code Playgroud)

  • 我使用`forward_as_tuple`或`tie`而不是`make_tuple`,因为你不需要复制`a` (4认同)

IlB*_*dus 5

怎么样std::apply( std::bind(&A::MemFun, &a, std::placeholders::_1, std::placeholders::_2), parm2 );

编辑包括建议和占位符

  • 最好使用lambda而不是`std :: bind`. (2认同)
  • 使用`bind`是可以的,但是这个解决方案复制`a`所以最好使用`std :: ref(a)`或简单地用'&a`代替. (2认同)