C++是否具有SQL联合的等效功能



在SQL中,COALESCE(val_1, val_2, ... val_n)是一个变量函数,它返回第一个非null参数,否则为null。

现在,在C++中,我们有可以为null的指针,但也有自C++17以来的std::optional,还有std::variant,它可以为null或保持单态类型。

C++中是否存在一些标准库函数,它接受多个可为null(或可为emptyable(的对象,并返回第一个非null对象?如果没有,是否有人提出过一个,例如在一元编程的背景下?

不知道,但你可以很容易地写一个:

template<typename T>
auto coalesce(T&& t) { return *t; }
template<typename T1, typename... Ts>
auto coalesce(T1&& t1, Ts&&... ts)
{
if (t1)
{
return *t1;
}
return coalesce(std::forward<Ts>(ts)...);
}

您也可以将其作为运算符(例如,在命名空间中,这样就不会污染全局运算符(或将其作为自定义运算符。


上面解决了传递可为null的类型时的问题。根据请求,这里有一个版本适用于您希望混合可为null和不可为null的情况——当然,对于不可为nullable,它将返回第一个不可为Null的。这使用C++20:

template<typename T1, typename... Ts>
auto coalesce(T1&& t1, Ts&&... ts)
{
if constexpr (requires { *t1; })
{
if constexpr (sizeof...(ts))
{
return coalesce(std::forward<Ts>(ts)...);
}
return *t1;
}
return std::forward<T1>(t1);
}

请注意,即使是这个版本也存在这样的问题,即您只能用一个底层类型来调用它(如中所示,std::common_type<T1, Ts...>必须存在(。如果您希望能够处理多个(可能(不相关的底层类型,您可以采用延续传递:

template<typename Cont, typename T1, typename... Ts>
auto coalesce(const cont& c, T1&& t1, Ts&&... ts)
{
if constexpr (requires { *t1; })
{
if constexpr (sizeof...(ts))
{
return coalesce(cont, std::forward<Ts>(ts)...);
}
return cont(*t1);
}
return cont(std::forward<T1>(t1));
}

相关内容

  • 没有找到相关文章

最新更新