C++ 为什么可以使用std::ref将成员函数用作可调用类型? 请考虑下面的模板函数,它调用一个可调用的函数,并对其进行评估,并返回结果(仅用于说明目的):

C++ 为什么可以使用std::ref将成员函数用作可调用类型? 请考虑下面的模板函数,它调用一个可调用的函数,并对其进行评估,并返回结果(仅用于说明目的):,c++,c++11,C++,C++11,它抱怨无法调用成员函数: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘f (...)’, e.g. ‘(... ->* f) (...)’ auto evaluate(F&& f, A&&... args) -> decltype(f(std::forward<A>(args)...)) 为什么这样做?如果包装的对象是可调用的,那么使引用

它抱怨无法调用成员函数:

error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘f (...)’, 
e.g. ‘(... ->* f) (...)’ auto evaluate(F&& f, A&&... args) -> decltype(f(std::forward<A>(args)...))

为什么这样做?

如果包装的对象是可调用的,那么使引用包装器可调用的功能对于将对函数对象的引用传递到标准算法等的能力至关重要

在这里,我们创建对函数对象的引用元组:

int main()
{
    struct A {
        void operator()() const {
            std::cout << "A\n";
        }
    };

    struct B {
        void operator()() const {
            std::cout << "B\n";
        }
    };

    A a;
    B b;

    auto ab = std::tie(a, b);

    std::get<0>(ab)();
    std::get<1>(ab)();
}
为什么这样做有效

因为
std::reference\u wrapper::operator()
是用神秘的
INVOKE
(直到c++14)和
std::INVOKE
(c++17)编写的

此处的文档:


如果包装对象可调用,则使引用包装可调用的功能是将对函数对象的引用传递到标准算法等的能力的基础

在这里,我们创建对函数对象的引用元组:

int main()
{
    struct A {
        void operator()() const {
            std::cout << "A\n";
        }
    };

    struct B {
        void operator()() const {
            std::cout << "B\n";
        }
    };

    A a;
    B b;

    auto ab = std::tie(a, b);

    std::get<0>(ab)();
    std::get<1>(ab)();
}
为什么这样做有效

因为
std::reference\u wrapper::operator()
是用神秘的
INVOKE
(直到c++14)和
std::INVOKE
(c++17)编写的

此处的文档:


因为标准库是指向此处文档的链接:@RichardHodges传递给成员函数的
这个
指针是什么?@songyuanyao提供了答案。因为标准库是指向此处文档的链接:@RichardHodges传递给成员函数的
这个
指针是什么“这里?”宋元耀回答。
template<typename F, typename... A>
auto evaluate(F&& f, A&&... args) -> decltype(std::ref(f)(std::forward<A>(args)...))
...
int main()
{
    struct A {
        void operator()() const {
            std::cout << "A\n";
        }
    };

    struct B {
        void operator()() const {
            std::cout << "B\n";
        }
    };

    A a;
    B b;

    auto ab = std::tie(a, b);

    std::get<0>(ab)();
    std::get<1>(ab)();
}
struct EqualAndCount
{
    EqualAndCount(char sought) : sought_(sought) {}

    template<class R>
    bool operator()(R const& r)
    {
        counter_++;
        return sought_ == r;
    }
    std::size_t counter_ = 0;
    char sought_;
};

int main()
{
    EqualAndCount eq('j');
    auto s = std::string("abcdefghijklmnop");
    auto i = std::find_if(s.begin(), s.end(), std::ref(eq));

    std::cout << "searched " << eq.counter_ << " chars";
    if (i == s.end())
        std::cout << " and did not find it\n";
    else
        std::cout << " and found it\n";
}
searched 10 chars and found it