代码之家  ›  专栏  ›  技术社区  ›  Mykola Golubyev

C++选择第一个非空元素

  •  1
  • Mykola Golubyev  · 技术社区  · 16 年前



    我已经实现了下面的函数,它应该返回第一个NOTNULL元素或者抛出一个异常。
    你能不能发明一个更经典、更短的名字,比如“max”、“min”、“pair”?

    template <typename T>
    T select_first_not_empty( const T& a, const T&b )
    {
        static T null = T();
    
        if ( a == null && b == null )
            throw std::runtime_error( "null" );
    
        return
            a != null ? a : b;
    }
    
    int main()
    {
        const int a1 = 2;
        const int b1 = 0;
    
        const int* a2 = 0;
        const int* b2 = new int(5);
    
        const std::string a3 = "";
        const std::string b3 = "";
    
        std::cout << select_first_not_empty( a1, b1 ) << std::endl;
        std::cout << select_first_not_empty( a2, b2 ) << std::endl;
        std::cout << select_first_not_empty( a3, b3 ) << std::endl;
    
        return 0;
    }
    
    3 回复  |  直到 16 年前
        1
  •  3
  •   bayda    16 年前

    下一步你可以试试

    template < typename T >
    T get_valuable( const T& firstValue, 
                    const T& alternateValue, 
                    const T& zerroValue = T() )
    {
        return firstValue != zerroValue ? firstValue : alternateValue;
    }
    
    // usage
    char *str = "Something"; // sometimes can be NULL
    std::string str2 ( get_valuable( str,  "" ) );
    
    // your function
    template <typename T>
    T select_first_not_empty( const T& a, 
                              const T& b, 
                              const T& zerroValue = T() )
    {
        const T result = get_valuable( a, b, zerroValue );
        if ( result == zerroValue )
        {
            throw std::runtime_error( "null" );
        }
        return result;
    }
    
        2
  •  2
  •   Salman A    16 年前

    ?? ,我相信这就是所谓的联合。

    || (短路逻辑OR)运算符也具有类似的功能:它不返回0或1,而是将计算的第一个参数的值返回为true:

    0 || 7
    

    返回7,而不是1或1 true 正如C\C++或C#程序员所期望的那样。

    C++所构建的最接近的是FixIIF算法:

    vector<int> vec;
    vec.push_back(0);
    vec.push_back(0);
    vec.push_back(7);
    
    vector<int>::iterator first_non_0 = 
        find_if(vec.begin(), vec.end(), bind2nd(not_equal_to<int>(), 0));
    
        3
  •  2
  •   Paul Tomblin    16 年前

    如果T的ctor做了任何有意义的事情,它看起来就像您每次都通过“先选择\u\u不\u空”来做三次。

    如果你想找一个更好的名字,甲骨文公司称之为类似的“联合”。

    不过,我不确定重点是什么。如果我真的想知道是否设置了某些内容,我会使用可空指针而不是引用。与使用带内值(如0或“”)相比,“NULL”是一个更好的指标,表明不设置变量的意图。