2

如果我试图定义一个指针,重载函数过载的指针重载函数

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的相应版本。

回答

2

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功能的各版本

你为什么这样做?函数指针用于基于应用程序状态的运行时多态性。简单的旧的重载工作正常,如果唯一的差异是参数类型。

如果你希望能够,比如说写,将调用后面定义过载,在客户端代码库,这样做如下:

void foo(int x) { printf("int\n");} 
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; 
} 

这样的lib呼吁类型重载它直到链接时间才真正意识到。

+0

如果main上面的decs在lib.h中,后面的代码可以做到以下几点: struct MYSTRUCT {double d; int x} void foo(MYSTRUCT m){printf(“mystruct \ n”); } ... MYSTRUCT ms = {3。14159,6}; foo(ms); foo(ms); 和lib会调用你的foo。 注意,使用这种技术,你必须非常小心隐式类型转换 – kylben

+0

抱歉,应该是callfoo(ms),那么lib会回调你的foo(MYSTRUCT ms); – kylben

+0

我这样做的原因是'funpointer'在运行时在几个函数之间交替。这些函数被重载以接受整数和字符,这就是我遇到的问题。我宁愿不将这些重载函数分解为常规函数(因为这需要在其他地方更改大量代码),但我认为我必须遵循这一点。 – Malabarba

2

没有办法。您不能在同一个作用域中使用相同名称的两个变量。

1

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

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

1

你不能用函数指针来做......参数列表是类型的一部分,所以任何给定的函数指针一次只能对应一个特定的重载。尽管如此,你也许可以用函数对象来伪装它,这取决于你需要做什么。

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)并提取该函数的两个版本。但正如我所表明的那样,现在您不仅限于具有相同名称的功能,甚至仅限于功能。该对象也比以前更大,并且可能涉及一些堆分配。

0

这可能被认为是“笨重”,但你可以做一些类似如下:

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