2010-04-26 124 views
4

我意識到標準C++只能通過參數類型選擇函數,而不是返回類型。即我可以這樣做:C++按返回類型選擇函數

void func(int); 
void func(double); 

但不

double func(); 
int func(); 

凡在前者,很明顯,在後者,它是ambigious。是否有任何擴展讓我告訴C++通過返回類型選擇使用哪個函數?

謝謝!

+0

不是http://stackoverflow.com/questions/ 226144/puzzle-overload-ac-function-according-the-the-return-value問同樣的問題? – jjxtra 2010-04-26 23:06:21

+0

http://stackoverflow.com/questions/1927587/methods-overriding-and-overloading – 2010-04-26 23:10:51

回答

10

在同一個作用域中不能有兩個函數具有相同的名稱和簽名(即參數類型)。通過使f()回報與重載轉換運算符代理

int x=f(); 
double x=f(); // different behaviour from above 

:然而,你可以創建一個函數,將不同的表現取決於什麼變量分配的結果,象這樣

struct Proxy 
{ 
    operator double() const { return 1.1; } 
    operator int() const { return 2; } 
}; 

Proxy f() 
{ 
    return Proxy(); 
} 

參見http://ideone.com/ehUM1

這並不是說此特定的用例(返回不同數量的)是有用的,但也有 對於這個成語用途。

8

如果你有這兩個功能,其中之一應該編譯器挑,如果你簡單地稱爲:

func(); 

你可以得到你所要求的是使用專門的函數模板最接近(注這you want to be very careful when specializing function templates):

template <typename ReturnT> 
ReturnT func(); 

template <> 
double func<>() { return 42; } 

template <> 
int func<>() { return 0; } 

然後就可以調用它,如下所示:

func<int>(); 
func<double>(); 
+1

我也同意你的看法,但應該可以在你調用int i = func()的情況下實現, ;'並且只在沒有'void'函數時給出一個錯誤,並且'func()'在沒有附帶賦值的情況下被調用。雖然我不喜歡那樣。 – 2010-04-26 23:03:44

0

因爲編譯器不知道你調用了哪個函數!

+0

不好的編譯器,不能找出收集結果的變量的類型... – 2013-08-27 15:21:43

+0

@JoanCharmant:在你看來,編譯器應該做什麼,當它看到'auto result = func();'?結果是什麼類型?該類型是否可以明確確定? – IInspectable 2016-12-11 14:57:25

0

否;實際上也很難實現。我依稀記得聽說這是一個P-NP問題。

0

沒有我所知道的。您最好以不同的方式命名函數,或者使用不同的參數讓編譯器(而不是您)區分它們。

另外,這樣做:

struct myReturnType { 
    int myInt; 
    double myDouble; 
}; 

myReturnType func() { 
    ... 
} 
4

爲什麼不只是他們的名字不同?如果他們回覆不同的事情,這聽起來像他們可能不同的事情。爲什麼混淆你的代碼?

+0

你是否同意返回類型在函數重載中不太重要? – Raindrop7 2016-12-09 00:52:48

+0

我認爲重要的是以任何形式返回最適合該方法的數據(即,如果它是數值,則適當的精度)。如果您的方法正在計算某個值到最接近的整數,則返回它,並使用static_cast聲明您很樂意轉換爲另一種類型,如果這是您在調用代碼中需要的。 – 2016-12-09 11:02:35

+0

如果你的方法正在計算一些精確到浮點數的東西,然後返回它,這取決於調用者決定如何正確處理小數部分(舍入,地板,天花板等)。至少在你作爲一個調用者的幻想中,你不會因爲一種方法而得到什麼...... – 2016-12-09 11:07:38

1

C++中有一個上下文,其中重載解析的結果取決於表達式左側的「返回類型」。它是函數指針值與函數地址的初始化/賦值。它使用左側大小的顯式對象以及由顯式類型轉換創建的臨時對象。

在你的情況下,它可以用來從兩個重載的函數中選擇一個特定的函數。例如:

int (*pfunc)() = func; // selects `int func()` 
int i = pfunc(); // calls `int func()` 

您可以使用此方法來迫使一個線路的過載的分辨率,雖然它看上去並不是很優雅

int i = ((int (*)()) func)(); // selects and calls `int func()` 

同樣,在你手動執行重載這種情況。 C++沒有任何特性會導致基於返回類型的隱式重載解析(除了我上面所說的)。

+0

這正是我所尋找的。謝謝! – 2016-12-09 00:18:32

0

這有點危險,但你可以創建你想要返回的不同類型的聯合,並將這兩個聯合成一個返回聯合的函數。例如:

typedef union { 
    double d; 
    int i; 
} my_union; 

my_union func(); 

然而,這將需要的功能和來電者以某種方式知道什麼數據類型期望的結果,並可能導致各種錯誤。你可以做到這一點,但我絕對不會推薦它。

0

函數重載需要每個表單的不同簽名,不包括返回類型。兩種或多種形式是正確的,如果只是和他們在列表參數的數量或至少一種類型或參數的順序不同,例如:

void print(); // 1 
void print(int, char); // 2 ok number of parameters 
void print(char, int); // 3 ok the order of parameters type 
int print(int, char); // 4 no the same signature as 2 except the return type