何时使用 std::invoke 而不是简单地调用可调用对象?

问题描述 投票:0回答:4

据我了解,

std::invoke
允许我做类似的事情:

std::invoke(f, arg1, arg2, ...);

有没有比简单地这样做更有利的场景:

f(arg1, arg2, ...);
c++ std c++17
4个回答
45
投票

如果可调用对象是指向成员函数的指针,那么您需要执行以下操作之一:

(arg1->*f)(arg2,...);
(arg1.*f)(arg2,...);

取决于

arg1
是什么。

INVOKE(及其官方图书馆对应物

std::invoke
)几乎就是为了简化这种混乱而设计的。

您可以使用

std::invoke
来支持代码的调用者传递 any 可调用,而不必使用 lambda 或对
std::bind
的调用来调整其调用站点。


14
投票
当您创建 lambda 并需要立即调用它时,

std::invoke
会很有用。如果 lambda 很大,后面的括号可能很难观察到:

[] (/* args */) {
    // many lines here
    // ...
} (/* args */)

std::invoke(
    [] (/* args */) {
        // many lines here
        // ...
    },
    /* args */);

3
投票

尝试在两个答案的基础上添加,一个是给出很好的理论解释,另一个是试图提供一个具体的例子。这是

std::invoke
让事情变得更好的一个很好的理由。

#include <functional>
#include <iostream>

struct foo
{
    void echo(){std::cout << "foo" << std::endl;};
};

int main()
{
    ////
    // Vanilla version of invoking .echo()
    foo(f);
    f.echo();

    ////
    // Pointer to *class* member function version
    void (foo::* pf)() =  &foo::echo;
    foo obj;
    
    (obj.*pf)();    // ugly
    // instead do ...
    std::invoke(pf, obj);

    // obj->echo(); <-- does not compile

    return 0;
}

-1
投票
#include <iostream>
#include <functional>
template< class Callable, typename ... Args>{}

    //f(args...);   // if arg1 is a class object pointer 
                    // we should use it like this(arg1.*f)(args...); 

    std::invoke(f, args...); //  now  every thing is ok
}

void foo(char c) {
    std::cout << "foo called\n";
}

int main()
{
    struct S {
        int f1(char c) {
            std::cout << "S::f1 called\n";
        }
        void operator()(char c) {
            std::cout << "S::operator() called\n";
        }
    };
    int (S:: * fptr)(char c) = &S::f1;
    S  obj;

    dosomething(fptr, obj, 'a');
    return 0;
}

© www.soinside.com 2019 - 2024. All rights reserved.