如何使用static_cast解决函数重载问题?

3
  void hello()
  {
    cout << "helloworld" << endl;
  }

  void hello(string s)
  {
    cout << "hello " << s << endl;
  }

  void doWork()
  {
    thread t1(static_cast<void ()>(&hello));
    thread t2(static_cast<void (string)>(&hello),"bala");
    t1.join();
    t2.join();
  }

错误:

thread.cc|19 col 42| error: invalid static_cast from type '<unresolved overloaded function type>' to type 'void()'                                                          
thread.cc|20 col 48| error: invalid static_cast from type '<unresolved overloaded function type>' to type 'void(std::string) {aka void(std::basic_string<char>)}'

我知道可以使用函数指针的typedef或者lambda表达式来完成。 但是使用static_cast不行吗?


5
static_cast<void(*)()>,也许是这样的吗? - R. Martinho Fernandes
4个回答

11

你必须将类型转换为函数指针类型(而不是函数类型)

thread t1(static_cast<void (*)()>(&hello));
                           ^^^

函数类型(例如void())是一种通过其参数和返回类型表示函数的类型。然而,在程序中无法有这些类型的变量(除了函数本身,它们是函数类型的左值)。但是,可以存在对函数的引用或指向函数的指针,你可能想要使用后者。

当你尝试创建函数类型的变量(或临时对象)时(例如你typedef一个函数类型,或将其用作模板参数),其使用是可以的。 std::function<void()>仅使用该参数来指定其参数和返回类型,因此其设计者决定使用这种简洁的语法。在内部,它不会尝试创建具有该类型的变量。


成功了!但是什么是函数类型?例如,在使用vector<function<void()>> allFuncs;时,我不需要使用 * - balki
@balki:std::function 接受一个函数类型,而 &hello 是一个函数地址。这类似于 inta 的类型,int*&a 的类型,只是指向函数或数组的指针语法略微复杂,需要额外的括号。 - David Rodríguez - dribeas
或函数引用类型。在任何情况下,& 都是不必要的。 - Potatoswatter

1
该标准规定,当使用重载函数的地址时,可以使用该地址来消除歧义。这包括对适当类型变量的赋值或强制转换。
您可能遗漏的是,&hello 的类型不是函数签名,而是函数指针,因此应进行 void (*)() 和/或 void (*)(std::string) 的转换。
void (*f)() = &hello;                  // target variable determines
                                       // the correct overload
thread thr( (void(*)())&hello );       // or a cast (C or static_cast<>)
thread thr( static_cast<void(*)()>(&hello) );

0
如果您使用std thread,您只需编写以下内容。
std::thread(hello);
std::thread(hello, "blabla");

编译错误的第一行: thread.cc|19 col 20| error: no matching function for call to 'std::thread::thread(<unresolved overloaded function type>)' - balki
如果函数被重载了(就像这里一样),那么你需要一个强制类型转换来消除歧义。 - Mike Seymour

-1
为什么需要强制类型转换? 你可以使用std::bind或直接发送指针。
编辑: 正确,这是不可能的,绝对需要进行类型转换。

强制转换是必要的,以指定使用哪种重载。 - Mike Seymour
2
这个答案似乎没有理解问题的重点。在存在重载的情况下(在这种情况下有两个 hello 重载),函数名称本身的地址 (&hello) 是不明确的,语言确定函数的使用可以被编译器用来消除歧义。 - David Rodríguez - dribeas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接