2012-02-03 23 views
1

我正在考虑做一个take_timing函数,该函数将传递给它的任何函数的时间。通过任何函数这意味着这个回调所需的参数是调用者未知的。这将需要回调的参数。但是因为它不知道如何调用它,所以需要另一个回调函数,函数用户编写的回调的调用者。存根会是这样的:在C和C++中回调一个具有先前未知参数的函数

void take_timing(
    void (*callback)(), 
    void (*caller(void (*callback)(),void* args_struct), 
    void* args_struct 
) 
{ 
    // Start timer 

    caller(callback,args_struct); 

    // Stop timer, read timings, record... 
} 

void some_caller(void (*callback)(),void* args_struct) 
{ 
    // Cast "callback" to function signature 
    // Cast args_struct to some struct with args 
    // Call the callback with correct args signature 
} 

所以说到我的问题:

  1. 这可能吗?
  2. 它可以使用可变参数列表来简化它吗?怎么样?我对此很无奈......
  3. 有没有更好的方法呢?或者,对于每一个特定情况,只需要take_timing就好?
  4. 有没有OOP设计模式用于C++?

我自己放弃了这个,但是出于好奇,这可能是一些非常有用的见解。

+0

额外抽象的价值是什么?为什么不只用一个上下文指针来获取已知的回调函数类型?我猜这里我没有看到增值服务。 – 2012-02-03 19:26:49

回答

4

只需要一个仿函数作为模板参数。喜欢的东西:处理这种

template<typename F> 
nanoseconds take_timing(F f) { 

    auto start = high_resolution_clock::now(); 
    f(); 
    auto end = high_resolution_clock::now(); 
    return end - start; 
} 

long long factorial(int i); 

take_timing([](){factorial(20);}); // wrap call to function taking arguments in zero-argument lambda 
+0

嗯,这真的很棒,完美工作,不是介意令人难以置信,阅读,理解和使用非常简单。让我们拭目以待,看看是否有一种简单的C方法来做到这一点。 – 2012-02-03 20:55:28

3

您正在寻找varargs的支持,该支持确实存在于ANSI C中。如果您搜索它,将会产生巨大的Google搜索结果。这是一个随机的:http://www.eskimo.com/~scs/cclass/int/sx11b.html

+0

好吧,但有没有办法将'varargs'传递给另一个函数?在我们的例子中,'take_timing'得到'va_list'。但是它将如何调用'caller'并将参数从'va_list'传递给它? – 2012-02-03 20:58:48

+0

如果被调用的函数也可以带参数的va_list,那么是的。 IE,如果父函数是foo(va_list args),那么它肯定可以很容易地调用bar(va_list args),传递相同的参数集合(或者先使用它)。 – 2012-02-03 21:33:15

+0

我认为它使它成为一个有效的解决方案,尽管令人难以置信。事实上,这正是我第一次想到的,但我不确定传递宏处理的'va_list'是否有效。而且,当开始编码时,我发现它并不是很好的可用性设计,至少对我来说不是这样。 – 2012-02-03 21:46:07