【问题标题】:How to return nullptr equivalent from a C++ function whose return type is pair?如何从返回类型为对的 C++ 函数返回等效的 nullptr?
【发布时间】:2020-07-22 13:57:46
【问题描述】:
pair<int, int> findEmpty(int bo[9][9], int n){
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(bo[i][j]==0){
                return (make_pair(i, j));
            }
        }
    }
    //return nullptr; 
}

如果nullptr不能返回,有什么办法?

【问题讨论】:

  • 您可以返回一对表示它为空的两个数字。如果你想返回 null,你可以让函数返回一对指针。
  • return {}; 可能是一个解决方案
  • 替代方案取决于您想要的语义。这是一个错误吗?也许throw。这是一个“不可能”的价值吗?也许make_pair(-1, -1)。它是程序可以在没有的情况下工作的可选值吗? std::optional&lt;std::pair&lt;int,int&gt;&gt;。第二个选项有时也用来代替第三个。
  • 你说你的函数返回两个整数。因此,您必须返回两个整数,或者更改它以使返回类型不是两个整数。也许试试 optional>
  • 您的代码在循环中返回的唯一方法是一对值都为零或更大的值。任何一个具有负值的对都可以被认为是空的,例如make_pair(-1, -1)。您可能还希望在进入循环之前返回 if n &gt; 8

标签: c++ null return utility


【解决方案1】:

使用optional&lt;T&gt; 类型表示可能不存在的状态。

如果您使用 C++17,则可以使用 std::optional&lt;T&gt;,如果您使用 Boost,则使用 boost::optional&lt;T&gt;,等等。您甚至可以实现自己的 optional 版本。重点是使用一种语义类型来指示可能存在或不存在值。

使用 C++17 中的std::optional,您的代码变为:

optional<pair<int, int>> findEmpty(int bo[9][9], int n){
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(bo[i][j]==0){
                return make_pair(i, j);
            }
        }
    }
    return nullopt; 
}

虽然您可以通过返回类似标记的值(例如一对(-1, -1))来解决此问题,但这不是推荐的做法。这会强制检查调用方的特定哨兵值,这些值很容易被遗漏或遗忘 - 并且可能导致错误的哨兵值进入其他可能永远不会期望负值的算术或间接运算。

使用语义类型传达可空性有助于防止此类错误。

【讨论】:

    【解决方案2】:

    在 C++17 及更高版本中,您可以返回 std::optional,例如:

    std::optional<std::pair<int, int>> findEmpty(int bo[9][9], int n){
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                if (bo[i][j] == 0){
                    return std::make_pair(i, j);
                }
            }
        }
        return std::nullopt;
    }
    
    auto ret = findEmpty(...);
    if (ret)
    {
        // use ret.value as needed...
    }
    

    或者,您可以返回一个pair&lt;bool, pair&lt;int,int&gt;&gt;,其中bool 表示内部pair 是否有效:

    std::pair<bool, std::pair<int, int> > findEmpty(int bo[9][9], int n){
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                if (bo[i][j] == 0){
                    return std::make_pair(true, std::make_pair(i, j));
                }
            }
        }
        return std::make_pair(false, std::make_pair(-1, -1));
    }
    
    std::pair<bool, std::pair<int, int> > ret = findEmpty(...);
    if (ret.first)
    {
        // use ret.second as needed...
    }
    

    【讨论】:

      猜你喜欢
      • 2023-04-03
      • 2015-08-27
      • 1970-01-01
      • 1970-01-01
      • 2018-10-07
      • 2019-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多