不同数量的模板变量
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::set
、std::map
和 std::multimap
。
虽然模板类型有所不同(它是集合或映射本身,而不仅仅是 set/map 的模板参数),但使用 CTAD,您无需关心...
我必须根据 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::set
、std::map
和 std::multimap
。
虽然模板类型有所不同(它是集合或映射本身,而不仅仅是 set/map 的模板参数),但使用 CTAD,您无需关心...