【问题标题】:How to pass functions with different signatures as parameter to other function如何将具有不同签名的函数作为参数传递给其他函数
【发布时间】:2022-01-10 22:08:44
【问题描述】:

我正在努力解决以下问题,如果有人问过这个问题,我深表歉意。

我的代码中有多个部分在做类似的工作 - 它们主要在函数调用上有所不同:

int doSomething(string* s, int i) {
  ...
}

int doSomethingOther(string* s, string t) {
  ...
}

int main() {
  int num;
  string s;

  // do something with num
 
  // repeating part start
  string str1;

  // do some stuff
  
  int res1 = doSomething(&str1, num);

  cout << "res: " << res1 << " str1: " << str1 << endl;
  // end

  // do something with s
  
  // here we go again but with a different function call
  string str2;

  // do some stuff

  int res2 = doSomethingOther(&str2, s);

  cout << "res: " << res2 << " str2: " << str2 << endl;
  //end
  
  return 0;
}

是否可以定义一个通用函数来减少编写工作?一种可能性是为这个通用函数使用一个参数来指示应该使用哪个函数。另一方面,如果被调用的函数总是相同的,也可以使用函数指针:

...
void generalFct(int p, int(*doSomethingFct)(string* aString, int anInt)) {
  string s;

  // do some stuff

  int res = (*doSomethingFct)(&s, p);

  cout << "res: " << res << " s: " << s << endl;

  // do some other stuff
}
...
int main() {
  int num;

  // do something with num

  generalFct(num, &doSomething);

  ...
  
  // update num...

  generalFct(num, &doSomething);
}

但不幸的是,doSomethingdoSomethingOther 的签名不同(否则这将是一个解决方案),这就是我坚持的地方。是否有任何技术可以帮助我实现目标,例如:

int main() {
  int num;

  // do something with num

  generalFct(num, &doSomething);

  ...
  
  // update num...

  generalFct(num, &doSomethingOther);
}

【问题讨论】:

  • 也许使用模板?
  • 另一方面,您几乎不需要使用或传递指向标准容器的指针,包括字符串。为什么需要将指向 std::string 的指针作为参数传递?
  • 模板可以工作,但这完全取决于函数是否可以使用完全相同的代码,只需替换一些类型...
  • 您可以使用带有捕获的 lambda 来根据需要调整函数接口。
  • 顺便说一句——你不应该减少写作的努力,而是阅读的努力。 doSomething(param1, param2); 并不能完全帮助读者理解发生了什么。

标签: c++ function c++11


【解决方案1】:

你可以这样做:

#include <iostream>
#include <functional>
#include <string>

// std::function&& so it can accept temporaries
// std::function<int(void)> ensures you can only use
// functions returning an int. 
int generic_function(int p, std::function<int(void)>&& fn)
{
    auto value = fn();
    auto result = (p * p) + value;
    std::cout << result << "\n";
    return result;
}

int doSomething(const std::string& str, int i) 
{
    std::cout << "doSomething\n";
    return i;
}

int doSomethingOther(const std::string& str1, const std::string& str2) 
{
    std::cout << "doSomethingOther\n";
    return 12;
}

int main()
{
    // pass a lambda 
    generic_function(42, [] { return doSomething("1", 1); });
    generic_function(12, [] { return doSomethingOther("1", "2"); });

    return 0;
}

【讨论】:

    猜你喜欢
    • 2020-01-26
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 2020-09-13
    • 1970-01-01
    • 1970-01-01
    • 2014-06-04
    相关资源
    最近更新 更多