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);