2014-01-10 84 views
5

我不知道我能做些什麼來使這個工作在C++中。C++對和指針

的打算是:

pair<int, int> foo() { 
    if(cond) { 
    return std::make_pair(1,2); 
    } 
    return NULL; //error: no viable conversion from 'long' to 'pair<int, int> 
} 
void boo() { 
    pair<int, int> p = foo(); 
    if (p == NULL) { //error: comparison between NULL and non-pointer ('int, int' and NULL) 
    // doA 
    } else { 
    int a = p.first; 
    int b = p.second; 
    // doB 
    } 
} 

既然不能在C++中使用返回NULL,這裏是我的第二次嘗試:

pair<int, int>* foo() { 
    if(cond) { 
    return &std::make_pair(1,2); //error: returning address of local temporary object) 
    } 
    return nullptr; 
} 
void boo() { 
    pair<int, int>* p = foo(); 
    if (p == nullptr) { 
    // doA 
    } else { 
    int a = p->first; 
    int b = p->second; 
    // doB 
    } 
} 

什麼是正確的方法能夠返回一個對和一個空值。

+0

對於初學者來說,[避免對(http://maintainablecode.logdown.com/posts/158531 -stdpair考慮的有害)。 – Mark

+0

使用'new'在堆上分配對。 – Barmar

+4

@Barmar,不,只是沒有。 – Shoe

回答

8

嘗試通過引用傳遞一對foo(),然後從該函數返回一個指示成功或失敗的布爾值。像這樣:

bool foo(pair<int, int>& myPair) { 
    if(cond) { 
    myPair = std::make_pair(1,2); 
    return true; 
    } 
    return false; 
} 
void boo() { 
    pair<int, int> myPair; 
    if (!foo(myPair)) { 
    // doA 
    } else { 
    int a = myPair.first; 
    int b = myPair.second; 
    // doB 
    } 
} 

編輯:根據你在做什麼,你應該殺了foo()如果可能的話,評估condboo()

void boo() { 
    pair<int, int> myPair; 
    if (!cond) { 
    // doA 
    } else { 
    myPair = std::make_pair(1,2); 
    int a = myPair.first; 
    int b = myPair.second; 
    // doB 
    } 
} 
+1

謝謝,正是我需要的 – vtlinh

+1

編輯:正如我前面提到的,代碼片段是對問題的概括。生產代碼要複雜得多。 – vtlinh

10

你應該使用一個例外:

std::pair<int, int> foo() { 
    if(cond) { 
     return std::make_pair(1,2); 
    } 
    throw std::logic_error("insert error here"); 
} 

和你的boo功能:

try { 
    std::pair<int, int> p = foo(); 
    int a = p.first; 
    int b = p.second; 
} catch (std::logic_error const& e) { 
    // do something 
} 

here就是現場的例子。


在可選的可以使用std::optional(因爲C++ 14)或boost::optional:與升壓版本

std::optional<std::pair<int, int>> foo() { 
    if(cond) { 
     return std::make_pair(1,2); 
    } 
    return {}; 
} 

std::optional<std::pair<int, int>> p = foo(); 
if (p) { 
    int a = p->first; 
    int b = p->second; 
} else { 
    // do something 
} 

而且here的一個工作實例。

+2

我最喜歡這個解決方案。但是我總是非常討厭嘗試捕捉,特別是如果使用sjlj-gcc和seh-gcc。 'std :: optional'從C++中刪除14否?除此之外,我+1。 – Brandon

+2

+1正確的答案,但我實際上試圖避免嘗試趕上,如果它不是一個錯誤的條件。 – vtlinh

+0

@Jefffrey,可選的解決方案看起來很棒,我喜歡它。 – vtlinh

0

也許你正在尋找一個Nullable類型。沒有理由使用動態內存。這種方法完全是誇張的,不必要的,但它最符合你試圖用你的原始代碼實現的東西。

#include <iostream> 
#include <map> 

template <typename T, typename U> 
struct NullablePair 
{ 
    std::pair<T, U> pair; 
    T first = pair.first; 
    U second = pair.second; 
    NullablePair(const std::pair<T, U>& other) : pair(other) { } 
    NullablePair() { } 
    operator std::nullptr_t() const { 
     return nullptr; 
    } 
}; 

template <typename T, typename U> 
NullablePair<T, U> foo(bool cond) { 
    if(cond) { 
    return NullablePair<T, U>(std::make_pair(1,2)); 
    } 
    return NullablePair<T, U>(); 
} 

void boo() { 
    NullablePair<int, int> p = foo<int, int>(false); 
    if (p == nullptr) { 
    std::cout << "Nullptr.\n"; 
    } else { 
    int a = p.first; 
    int b = p.second; 
    } 
} 

int main() 
{ 
    boo(); 
} 
+0

是的,這是一個矯枉過正:) – vtlinh

0

如果你想保持函數簽名,那麼你可以使用pair。因此,在函數foo()的return語句中,可以返回std :: make_pair(NULL,NULL)。

pair<int, int> foo() 
{ 
    // Initialize cond 

    if(cond) 
     return std::make_pair(1,2); 
    return std::make_pair(NULL, NULL); 
} 

然後可以檢查是否p.first和p.second等於NULL在BOO()函數

+1

考慮到'std :: make_pair(0,0)'可能是一個有效的返回值... – Shoe