1


[根据更新要求更新问题]
我已经实现了以下函数,它应该返回第一个非空元素或抛出异常。
您还可以发明更经典和更短的名称,例如“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;
}
4

3 回答 3

3

你可以尝试下一步

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;
}
于 2009-03-10T19:11:37.737 回答
2

如果 T 的 ctor 做了任何重要的事情,看起来你每次通过“select_first_not_empty”都做了三遍。

如果您正在寻找更好的名称,Oracle 将类似的名称称为“COALESCE”。

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

于 2009-03-10T19:00:22.473 回答
2

C# 有一个类似功能的内置操作符??,我相信它被称为合并。

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

0 || 7

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

C++ 内置的最接近这一点的是 find_if 算法:

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));
于 2009-03-10T19:09:21.283 回答