所以我有一个函数,使用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/