c++ 获取重载集的函数对象

qybjjes1  于 2023-07-01  发布在  其他
关注(0)|答案(1)|浏览(132)

这段代码不起作用,因为&f只创建了一个指向两个f()函数之一的函数指针,所以编译器不知道是哪一个:

#include <iostream>
#include <string>

void f(int i) {
    std::cout << "f(int)" << std::endl;
}

void f(std::string str) {
    std::cout << "f(std::string)" << std::endl;
}

template<typename Callback>
void call(const Callback& callback) {
    callback(1);
    callback("a");
}

int main() {
    call(&f);
}

如果我改为创建一个模板lambda函数,它就能像预期的那样工作

call([](const auto& arg) { f(arg); });

有没有一种方法可以做到这一点,而不需要编写额外的lambda,它需要传递所有的参数?例如,使用std::bind表达式?或者语言中是否存在f的重载只能在函数调用表达式中解析的限制?

pieyvz9o

pieyvz9o1#

要调用的函数也可以通过static_cast来选择:

int main() {
    call(static_cast<void(*)(std::string)>(&f));
}

然而,一旦你决定调用哪个重载,它要么是int,要么是std::string
要同时调用callback(1);callback("a");,您需要在函数调用时(或稍后,但不是像上面那样在调用之前)执行重载解析。最简单的方法就是使用lambda。
lambda在概念上类似于

struct my_callable {
       template <typename T> 
       void operator()(const T& t) {
              f(t); // <---- overload resolution kicks in here
       }
 };

你也可以通过

struct my_callable2 {
     void f(int i) {
        std::cout << "f(int)" << std::endl;
     }
     void f(std::string str) {
        std::cout << "f(std::string)" << std::endl;
     }
 };

然而,lambda很可能是内联的,因此避免一个函数调用并没有什么真实的好处。而且你自己写函子也不会少一点样板。

相关问题