2014-01-10 55 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