不同数量的模板变量

Different amount of template variables

我必须根据 std::multiset 实施 class。这个想法是,当两个多重集进入同一个“视图”时,我的 class 需要对它们进行排序,生成运算符和迭代器等,但我基本上停留在第一步。问题是我需要创建相同的 class,只是模板变量的数量不同。主程序这样调用我的class,例如:

multisets_merge_view<int> mvi(a, b); //a and b are std::multiset<int>
multisets_merge_view<int, std::greater<int>> mvi(ga, gb); //ga and gb are std::multiset<int, std::greater<int>>

我需要将 g++ 编译器与 -fsanitize=address,leak,undefined -O3 -Wall -Wextra -Werror

一起使用

解决这个问题的一个非常简单的方法是为比较器提供一个默认参数:

template <typename T, typename C = std::less<T>>
class multisets_merge_view { /* ... */ };

从 C++17 开始,您可以依赖 class template argument deduction,这可以大大简化模板的使用 class – 您甚至不必为以下内容提供推导指南:

template <typename T, typename C>
class multisets_merge_view 
{
public:
    multisets_merge_view (std::multiset<T, C>& x, std::multiset<T, C>& y);
};

// the deduction guide (but not necessary)
template <typename T, typename C>
multisets_merge_view(std::multiset<T, C>& x, std::multiset<T, C>& y)
    -> multisets_merge_view <T, C>;

这允许使用您的 class 如:

multisets_merge_view mvi(a, b);
multisets_merge_view mvi_g(ga, gb);

注意:不再需要指定任何模板参数...

另一种变体是您的观点 class 完全通用:

template <typename T>
class generic_merge_view
{
    using Compare = typename T::key_compare;
public:
    generic_merge_view(T& x, T& y)
    {
        // just for demonstration
        Compare c;
        for(auto ix = x.begin(), iy = y.begin(); /*...*/; ++ix, ++iy)
        {
            if(c(*ix, *iy)) 
            {
                // do something
            }
        } 
    }
};

你可以从 duck-typing 中获益:只要类型提供模板所需的所有功能——在本例中是 key_compare typedef 和迭代的能力——你就可以使用它,这将包括例如std::setstd::mapstd::multimap

虽然模板类型有所不同(它是集合或映射本身,而不仅仅是 set/map 的模板参数),但使用 CTAD,您无需关心...