2011-09-07 37 views
1

我很感興趣,如果我可以從一個函數返回更多的值。例如考慮這樣一個函數:擴展的歐幾里得算法。基本步驟描述如下 輸入是非負整數a和b; 輸出是一個三元組(d,i,j),例如d=gcd(a,b)=i*a+j*b。 只是爲了澄清我的問題的目標,我會寫一個簡短的遞歸代碼:如何從C++函數返回多個值?

if (b==0) return (a,1,0) 
     q=a mod b; 

設R是這樣的:a=r*b+q;

(d,k,l)=extendedeuclidean(b,q); 
    return (d,l,k-l*r); 

怎樣才能返回三重?

+1

考慮使用標點符號下一次。這很難閱讀。 – Fiktik

+0

是的肯定謝謝 –

回答

0

只需創建一個適當的數據結構來保存三個值並返回。

struct extmod_t { 
    int d; 
    int i; 
    int j 
    extmod_t(int d, int i, int j) : d(d), i(i), j(j) { } 
}; 

… 

extmod_t result = extendedeuclidean(b, q); 
return extmod_t(result.d, l, k - l * r); 
+0

只有一個問題,當有遞歸調用函數時如何做到這一點? –

+0

@ user466534你是什麼意思?遞歸不需要特殊的處理。 –

8

您可以創建一個std::tupleboost::tuple從三重對(如果你不使用的C++ 0x)並返回。

+0

@AndyT:更正了 –

0

要麼創建一個封裝三元組,然後返回此類的實例或使用3個​​引用參數的類。

+0

-1用於參考參數。這是一個可怕的濫用參數,完全沒有必要,使得該功能使用起來不方便。 –

+1

@Konrad只有在調用者已經準備好使用該對象時才使用它。如果代碼的其餘部分使用獨立的字段,那麼「解包」返回的對象實際上可能比直接按引用傳遞字段更醜。 –

+1

打開一個元組的包不是很麻煩:http://ideone.com/A9lGj。 – visitor

0

我通常會發現,當我需要從函數返回兩個參數時,使用STLstd::pair是有用的。

你總是可以將對彼此堆疊在一起(例如std::pair <int, std::pair <int, int> >),並用typedef-s幫助自己或定義它以使其更容易訪問,但是當我嘗試這樣做時,我的代碼最終變得凌亂和不切實際,使用。然而,對於兩個以上的參數,我建議讓你擁有自己特定的數據結構來存儲你所需要的信息(如果你要返回多個值,那麼他們很可能會以某種方式強有力地邏輯連接,並且最終可能會再次使用相同的結構)。

E.g.我需要一個函數返回行的斜率(1參數),這很好。然後,我需要擴展它以返回該行的參數表示的兩個參數(y = k*x + l)。兩個參數,仍然很好。然後我想起這條線可以是垂直的,並且我應該添加另一個參數來指示(然後沒有參數表示)...在這一點上,嘗試使用現有的數據類型變得太複雜,所以我輸入了我的自己的線結構,並最終在以後的所有項目中使用相同的結構。

2

正如Tony The Tiger所暗示的那樣,您可以使用tuple。它包含在C++ 11標準中,新的編譯器已經支持它。它也在boost中實施。 對於我的ibm xlC編譯器元組,它位於std :: tr1名稱空間中(嘗試使用MSVC10 - 它位於std名稱空間中)。

#include <cstdio> 
#include <tuple> 

// for MSVC 
using namespace std; 

// for xlC 
//using namespace std::tr1; 

// for boost 
// using namespace boost; 

typedef tuple<int, float, char> MyTuple; 
MyTuple f() { 
    return MyTuple(1, 2.0f, '3'); 
} 

int main() { 
    MyTuple t = f(); 
    printf("%i, %f, %c\n", get<0>(t), get<1>(t), get<2>(t)); 
} 

方xIC編譯爲TR1:

xlC -D__IBMCPP_TR1__ file.cpp 

方xIC編譯升壓:

xlC file.cpp -I/path/to/boost/root