2016-12-05 105 views
1

的功能分配重載函數函數指針作爲默認值

foo(int (*fnptr)(int)); 

我想提出一個默認值的函數指針int bar(int)

即指針的默認值是bar

bar也過載爲

double bar (double); 
bool bar (bool); 

我該如何賦值?

我試圖

foo (int (*fnptr)(int) = bar); 

,但它不工作。

編輯我使用MS Visual Studio和得到錯誤代碼C2440

'默認參數':無法從 '重載函數' 到 'Error_C(__cdecl *)(HMstd ::例外)' 轉換

我的實際功能是我定義的命名空間HMstd

virtual Error_C execute_protocol(Error_C(*execute)(exception ex) = HMstd::MErr); 

exception類的成員函數和函數是

Error_C MErr(Error_C code); 
Error_C MErr(char* desc); 
Error_C MErr(exception ex); 

其中Error_C另一類

這是三個重載函數的定義HMstd::MErr

Error_C HMstd::MErr(Error_C code) 
{ 
    std::cout << "\n\nError: An Error Of Code " << int(code) << "  Occured....\n\n"; 
    return SUCCESS; 
} 

Error_C HMstd::MErr(char* desc) 
{ 
    if (desc == NULLPTR) 
     return E_NULLPTR; 
    std::cout << desc; 
    return SUCCESS; 
} 

Error_C HMstd::MErr(exception ex) 
{ 
    bool Nullar = TRUE; 
    bool uninit; 
    for (int i = 0;i < 200;i++) 
     if (ex.description[i] != '\0') 
      Nullar = FALSE; 
    uninit = (int(ex.code) == -201) && Nullar; 
    if (uninit) 
    { 
     return UNINIT_PARAMETER; 
    } 
    MErr(ex.code); 
    MErr(ex.description); 
    return SUCCESS; 
} 
+2

你有什麼錯誤?我看起來很好。 – Quentin

+1

編譯這樣的代碼我沒有問題 - 你可以提供[MCVE](http://stackoverflow.com/help/mcve)嗎?你正在使用哪種編譯器/版本/平臺? – Holt

+0

是的。 'int bar(int);雙重酒吧(雙人);布爾吧(布爾); void foo(int(* fnptr)(int)= bar); int main(){}'爲我編譯並運行。 –

回答

2

快速回答:

使用型鑄造

短代碼:

// ... 
int bar (int) { 
    cout << "Right\n"; 
    // bar(true); // just in case you want to invoke bool bar(bool) 
    // bar(0.0f); 
    return 0; 
} 
// ... 
int foo (int (*ptr) (int) = static_cast<int (*) (int)>(bar)) { 
    return ptr(0); 
} 
// ... 

全碼:

#include <iostream> 

using namespace std; 

int bar (int) { 
    cout << "Right\n"; 
    // bar(true); // just in case you want to invoke bool bar(bool) 
    // bar(0.0f); 
    return 0; 
} 

bool bar (bool) { 
    return false; 
} 

double bar (double) { 
    return 0; 
} 

int foo (int (*ptr) (int) = static_cast<int (*) (int)>(bar)) { 
    return ptr(0); 
} 

int main() { 
    return foo(); 
} 

交代:

你有一個以上的bar所以我不能把= bar作爲默認參數。正因爲如此,您必須指定哪個bar。我使用了類型轉換,因此編譯器可以指定其中的一個bar。我看到你只提供了兩個barbool bar(bool)double bar(double),但你不能將這些函數中的任何一個轉換爲int bar(int)(如果gcc允許,程序可能工作不正常,尤其是double bar(double)),所以你需要調用其中的一個新int bar(int)

注:

您還可以使用不安全 C風格的類型轉換(int (*)(int)) bar,而不是static_cast<int (*) (int)>(bar)但是這是C++

如果您使用的是Turbo C++,上面的代碼可能不會工作,所以您可能更喜歡C風格的類型轉換,或者只是切換到GCC。

也可參見:

How do I specify a pointer to an overloaded function?

+1

在C++中更好的使用'static_cast' –

+0

我擔心'static_cast'對於這樣一個簡單的問題來說太「先進」了。無論如何,我會更新它。 – DMaster

+3

好'static_cast'在這裏更加充足,因爲它可以讓我們避免做一些可能會導致UB的事情:) –

1

也許您正在尋找這樣的事情:

#include <iostream> 
#include <functional> 

double bar (double) { 
    std::cout << "double bar (double) called" << std::endl; 
    return 0.0; 
} 
bool bar (bool) { 
    std::cout << "bool bar (bool) called" << std::endl; 
    return false; 
} 

void foo(std::function<int(int)> fn = [](int p) -> int{ return bar(static_cast<double>(p)); }) { 
    fn(2); 
} 

int main() { 
    foo(); 
} 

輸出:

雙杆(雙)稱爲

[live demo]

,你也可以用指針代替std::function的使用的功能,如果你被慾望:

void foo(int (*fn_ptr)(int) = +[](int p) -> int{ return bar(static_cast<double>(p)); }) { 
    fn_ptr(2); 
} 

[live demo]

+0

我剛開始看看lambda函數。我無法理解代碼非常抱歉 – WARhead

0

答案很簡單。我宣佈了功能

Error_C MErr (exception ex); 

類的聲明後,exception

所以exception類的虛成員函數不能使用該功能MErr我沒有辦法來實現這個默認參數的這種特殊的過載。