c++ - 有没有一种通用的方法来传递需要较少工作的重载方法的指针(比我的示例)

标签 c++ templates function-pointers generic-programming

所以我有一个函数,使用C++ 17,我可以从任何对象应用任何方法:

#include <functional>

template <typename Object, typename Method, typename ... Args>
void ApplyMethod (Object && object, Method && method, Args && ... args)
{
    std::invoke(method, object, args...);
}
我要问的是:有没有一种方法可以改进此方法,以在方法重载时减少函数调用者的工作。
与重载方法一起使用的示例:
#include <iostream>

class Foo
{
    int bottles;

public:

    void Edit ()
    {
        bottles = 666;
    }

    void Edit (int number)
    {
        bottles = number;
    }
    
    void Talk () const
    {
        std::cout << bottles << " bottles of beer of the wall" << std::endl;
    }
};

class Bar
{
    Foo foo;
    
    void TrickEdit (int number)
    {
        // Because Foo::Edit is overloaded, we need to do some work:
    
        using Method = void (Foo::*)(int);
    
        Method ptr = &Foo::Edit;
        
        ApplyMethod(foo, ptr, number);
    }
    
    void TrickTalk () const
    {
        // it's a lot neater when the method isn't overloaded:
    
        ApplyMethod(foo, &Foo::Talk);
    }

public:

    void Trick ()
    {
        TrickEdit(900);
        TrickTalk();    
    }   
};


int main ()
{
    Bar().Trick();
    
    return 0;
}
我正在尝试执行功能上的工作。问题似乎在于&Foo::Edit具有两个不同的位置,具体取决于我们所指的是Edit
在Stroustrup和其他知名作者的C++ FAQ - Pointers to member functions中,我读到:

Question: I need something like function-pointers, but with more flexibility and/or thread-safety; is there another way?

Answer: Use a functionoid.

Question: What the heck is a functionoid, and why would I use one?

Answer: Functionoids are functions on steroids. Functionoids are strictly more powerful than functions, and that extra power solves some (not all) of the challenges typically faced when you use function-pointers. [...] Functionoids don’t solve every problem encountered when making flexible software, but they are strictly more powerful than function-pointers and they are worth at least evaluating. In fact you can easily prove that functionoids don’t lose any power over function-pointers, since you can imagine that the old-fashioned approach of function-pointers is equivalent to having a global(!) functionoid object. Since you can always make a global functionoid object, you haven’t lost any ground. QED.


鉴于编程的“力量”基本上是在减少工作重复,并且使用正常功能,我们将避免在我的问题中概述的 call 现场进行额外的工作,因此FAQ的答案暗示应该有一个解决方法使用功能类。但是,对于我的一生,我看不到在这种情况下函数类将如何提供帮助。

最佳答案

您可以编写一个变量模板,以指定应使用的Args...

template <typename... Args>
struct Overload {
    template<typename R, typename O>
    operator R(O::*)(Args...) (R(O::*p)(Args...)) const { return p; }
    template<typename R, typename O>
    operator R(O::*)(Args...) const (R(O::*p)(Args...) const) const { return p; }
};

template <typename... Args>
Overload overload;

哪个像
struct A
{   
    void Do() { std::cout << "Do no parm" << std::endl; }
    void Do(int) { std::cout << "Do 1 parm" << std::endl; }
    void Do(int,int) { std::cout << "Do 2 parms" << std::endl; }
};  

template <typename Object, typename Method, typename ... Args>
void ApplyMethod (Object && object, Method && method, Args && ... args)
{
    std::invoke(method, object, args...);
}

int main()
{   
    A a;
    ApplyMethod( a, overload<>(&A::Do));
    ApplyMethod( a, overload<int>(&A::Do), 1); 
    ApplyMethod( a, overload<int, int>(&A::Do),1,2);
}

这就是Qt does的现代信号和插槽。

关于c++ - 有没有一种通用的方法来传递需要较少工作的重载方法的指针(比我的示例),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60575881/

相关文章:

c++ - Clion mongodb 依赖设置

c++ - QODBC3 无法绑定(bind)到变量

c++ - 从 .obj 文件在 OpenGL 中绘制四边形

c - 从 C 中的通用 (void *) 列表中删除元素

c++ - 既然可以使用函数引用,为什么还要使用仿函数

c++ - qt程序中strstr的奇怪行为

javascript - mapbox 由于模板未初始化

c++ - 如何将 boost::intrusive_ptr 用于类模板中的私有(private)嵌套类

templates - AWS Cloudformation 安装自定义二进制文件时出现问题

c - If 语句与函数指针