重载指向重载函数的指针

Overload a pointer to an overloaded function

本文关键字:重载 指针 函数      更新时间:2023-10-16

如果我尝试定义一个指向重载函数的指针

void myprint(int );
void myprint(const char* );
void (*funpointer)(int) = myprint;

编译器理解funpointer应该指向与其参数匹配的myprint版本。相反,我希望funpointer也被重载。
我试着简单地添加几行,比如

void myprint(int );
void myprint(const char* );
void (*funpointer)(int);
void (*funpointer)(const char *);
void funpointer = myprint;

但是随后编译器抱怨funpointer的声明冲突(很明显)。

是否有一种方法可以实现我正在寻找的?我希望指针的行为作为一个重载函数。所以我可以把它命名为funpointer(1)funpointer("Hey."),它将作为myprint的各自版本。

你为什么要这样做?函数指针用于基于应用程序状态的运行时多态性。如果唯一不同的是参数类型,那么普通的重载就可以正常工作。

如果您希望能够编写一个库,该库将调用稍后在客户端代码中定义的重载,请执行以下操作:

void foo(int x) { printf("intn");}
void foo(const char* c){ printf("char*n"); }
template <class T> void callfoo(T t) { foo(t); }
int main(int argc, char* argv[])
{
    int x = 3;
    callfoo(x);
    const char* p = "Hello world";
    callfoo(p); 
    return 0;
}

这允许库调用重载类型,它实际上并不知道,直到链接时间

不行。

指针是类型,不能重载。只有函数可以被重载。

在c++中没有办法实现指针的重载。

你不能用函数指针…实参列表是类型的一部分,因此任何给定的函数指针一次只能对应一个特定的重载。但是,您可以使用函数对象来替换它,这取决于您需要做什么。

struct MyPrint {
    void operator()(int i) { int_f(i); }
    void operator()(const char* c_str) { str_f(c_str); }
    std::function<void(int)> int_f;
    std::function<void(const char*) str_f;
};
void print_int(int i) { cout << i << endl; }
void print_string(const char* str) { cout << str << endl; }
int main() {
  MyPrint p;
  p.int_f = print_int;
  p.str_f = print_string;
  p(5);
  p("Hi");
}

你失去了按名称重载的能力;您不能添加一个set_functions(f),它接受函数名并提取函数的两个版本。但正如我所展示的,现在您不限于具有相同名称的函数,甚至不限于函数。对象也比以前大,并且可能涉及到一些堆分配。

这可能被认为是"笨拙的",但您可以这样做:

template<typename T>
struct funcptr_struct
{
    typedef T type;
    static type ptr;
};
template<> funcptr_struct<void(*)(int)>::type funcptr_struct<void(*)(int)>::ptr = myprint;
template<> funcptr_struct<void(*)(const char*)>::type funcptr_struct<void(*)(const char*)>::ptr = myprint;

然后可以使用如下语法调用myprint函数的每个版本:

funcptr_struct<void(*)(int)>::ptr(5);