默认模板类Lambda

Default template class lambda

本文关键字:Lambda 默认      更新时间:2023-10-16

,假设您有一个模板函数,该功能可能采用"收集",可能是"转换" lambda:

template<typename Collection, typename Transform>
void DoIt(const Collection &c, Transform transform)
{
    for(auto &item: c)
    {
        std::cout << transform(item);
    }
}

,但我想要一个lambda的默认转换,它只是返回对其参数的引用。如果收集:: value_type支持&lt;&lt;进入流,您只需致电

DoIt(collection);

但是,如果没有,您可以致电:

DoIt(collection, [](const collection::value_type &item) { item.ToString();});

可能最简单的答案是超载该函数,一个调用另一个呼叫:

template<typename Collection, typename Transform>
void DoIt(const Collection &c, Transform transform)
{
    for(auto &item: c)
    {
        std::cout << transform(item);
    }
}
template<typename Collection>
void DoIt(const Collection &c)
{
    DoIt(c, [](auto &item) -> decltype(item) { return item; });
}

,或者,如果您真的只需要一个模板,则需要一个像功能的类别,只需通过其参数。

namespace std_compat {
    struct identity
    {
        template<typename T>
        constexpr T&& operator()(T&& obj) const noexcept
        { return std::forward<T>(obj); }
        using is_transparent = void;
    };
}
template<typename Collection, typename Transform = std_compat::identity>
void DoIt(const Collection &c, Transform transform = {})
{
    for(auto &item: c)
    {
        std::cout << transform(item);
    }
}

这也允许用户执行诸如DoIt<decltype(c), std::negate<>>(c);之类的事情。这似乎不是特别好。

注意std::identity出现在C 20。

// Function object that returns a reference to x
struct SelfReference
{
    template<class T>
    auto operator()(T& x) const -> T&
    {
        return x;
    }
};
// default template argument selects SelfReference    
// also note default argument
template<typename Collection, typename Transform = SelfReference>
void DoIt(const Collection &c, Transform transform = Transform())
{
    for(auto &item: c)
    {
        std::cout << transform(item);
    }
}