如何在 C++ 中使用函数作为类的初始化程序 [重复]
Posted
技术标签:
【中文标题】如何在 C++ 中使用函数作为类的初始化程序 [重复]【英文标题】:How to use a function as an initializer for a class in C++ [duplicate] 【发布时间】:2019-08-19 03:30:34 【问题描述】:我正在尝试创建一个在初始化时接受函数作为参数的类。理想情况下,该功能应该已经存在。我知道在 Python 中,我可以这样做:
class TestClass:
def __init__(self, function_parameter):
self.fp = function_parameter
def executeFP(self):
self.fp()
def testFunction():
print("test")
q = TestClass(testFunction)
q.executeFP()
如何在 C++ 中做到这一点? (如果重要的话,我使用的是 Arduino)
【问题讨论】:
如果人们在这样做后解释为什么他们对帖子投了反对票,我会很高兴,只是反对票并不能告诉我任何事情 我猜可能有人对缺乏尝试不满意? @WeaktoEnumaElish 它不应该是一个匿名函数,它应该是一个已经存在的函数。 std::function 和模板方法都适用于现有函数。 您可能不应该尝试从 Arduino 代码 sn-ps 或 SO答案中学习 C++。任何好的 C++ 书籍都应该以不止一种方式解释将函数作为参数传递。它确实是 C++ 的基础部分。 【参考方案1】:Arduino 没有std::function
,因为 AVR GCC 不附带标准库,因此 cmets 中的这些建议不适用于该特定平台。
如果您需要 Arduino 或其他嵌入式平台的类似行为,您可以使用ETL 的etl::function
或etl::delegate
,或创建自己的实现。 std::function
使用堆分配进行类型擦除,这通常不是嵌入式的好选择。
最简单的实现是使用 C 风格的函数指针:
// Generic definition of the function type
template <typename F>
class function;
// R: return type
// Args: Any arguments a function can take
template <typename R, typename... Args>
class function<R(Args...)>
public:
// Type definition of the equivalent C function pointer
using function_type = R (*)(Args...);
// Default constructor: empty function.
// Never call the function while not initialized if using it this way.
function() = default;
// Constructor: store the function pointer
function(function_type f) : function_ptr(f);
// Call operator: calls the function object like a normal function
// PS: This version does not do perfect forwarding.
R operator()(Args... args) return function_ptr(args...);
private:
function_type function_ptr;
;
// A helper function can be used to infer types!
template <typename R, typename... Args>
function<R(Args...)> make_function(R (*f)(Args...))
return f;
Live example,有一些用例。
当然,你也可以只使用 C 指针来处理这种情况,但是这个类可以扩展为其他类型。如果您需要更复杂的行为,例如仿函数、成员函数和捕获 lambda,请参阅我上面引用的 ETL 实现。
【讨论】:
我试图在我的课堂上实现这个,但它给出了一个错误,说“没有匹配函数调用'functionusing function_type = void(*)()
这样的类型并在你的类中使用它。【参考方案2】:
您可以执行以下操作: (不确定Arduino是否可以像下面这样)
template <typename F>
class TestClass
public:
TestClass( F func )
:m_func(func)
void executeFP()
m_func();
private:
F *m_func;
;
void doStuff()
std::cout << "test" << std::endl;
bool doAnotherStuff( )
std::cout <<"test " << 40 +2 << std::endl;
return true;
int main()
TestClass<decltype(doStuff)> someObj ( doStuff );
TestClass<decltype(doAnotherStuff)> someObj2 ( doAnotherStuff );
someObj.executeFP();
someObj2.executeFP();
见here
【讨论】:
m_func(func)
- 它们属于不同类型(F*
和 F
)...
@Aconcagua foo
被声明为具有 F
类型,它实际上具有 F*
指针类型。虽然 decltype(doStuff)
的计算结果为 void ()
而不是 void (*)
,但是该函数在 someObj ( doStuff )
处可以隐式转换为指向自身的指针,因此没有错误。
嗯,好的,但随后就失去了与仿函数一起使用的资格。跳过与decltype(&doStuff)
结合使用的指针可以避免这种情况(或者我们可以只推导出模板参数,如果 C++17 可用...)。以上是关于如何在 C++ 中使用函数作为类的初始化程序 [重复]的主要内容,如果未能解决你的问题,请参考以下文章