c++ - 可变默认参数

标签 c++ templates c++11 variadic-templates

前几天我想编写一个多维 map ,并偶然发现了以下问题。通常,对于 map ,您需要 key ,一个cmp (或 less )和 hash -类型。在多维 map 中,您需要为 map 的每个维度提供其中一个。

现在,如何声明 map 类?我尝试了以下方法:

template<typename val, typename ... key, typename ... cmp, typename ... hash>
class multimap;

由于明显的原因它不起作用,所以我想出了一个解决方法:

template<typename Key,
         typename Cmp = std::less<Key>,
         typename Hash = std::hash<Key>>
struct Dimension
{
  using Key = Key;
  using Cmp = Cmp;
  using Hash = Hash;
};
template<typename Val, typename ... Dimensions>
class multimap;
// Example usage:
multimap<float, Dimension<int>, Dimension<float, some_cmp_t>> my_map;

虽然这有效,但它会强制用户重复 Dimension<...>到处都是,如果他只是想声明一个简单的 map ,比如(int, int, int) -> float,那就很不幸了看起来像 multimap<float, Dimension<int>, Dimension<int>, Dimension<int>> 。我该怎么做才能让用户更满意?

请注意,使用上面的声明,也无法从为每个维度采用 Comparator 的潜在构造函数中推断出特定维度的类型。

如何使声明易于使用,例如

  • multimap<float, int, int, int>结果 (int, int, int) -> float
  • mulitmap<float, Dimension<int, some_cmp_t, some_hash_t>, int>结果 (int, int) -> float在第一维上使用特殊的比较器和哈希函数。

最佳答案

通过将每种类型传递给辅助特征,将非维度转换为维度:

template <typename T>
struct DimensionFilter
{
    using type = Dimension<T>;
};

template <typename Key, typename Cmp, typename Hash>
struct DimensionFilter<Dimension<Key, Cmp, Hash>>
{
    using type = Dimension<Key, Cmp, Hash>;
};

然后每当您引用multimap的参数包时,请使用:

typename DimensionFilter<Dimensions>::type...

DEMO

您还可以将 multimap 设为别名模板,以便它引用的实际类型仅接收 Dimensions:

namespace detail
{
    template <typename Val, typename ... Dimensions>
    struct multimap {};
}

template <typename Val, typename ... Dimensions>
using multimap = detail::multimap<Val, typename DimensionFilter<Dimensions>::type...>;

DEMO 2

关于c++ - 可变默认参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33042166/

相关文章:

c++ - Lambdas 并将指针类作为参数传递

c++ - 模板错误 : nontype ".. [with T=T] is not a type name"

c# - C++中的虚函数重写

c++ - 任何好的 C++/C NNTP 库?

C++ 从非右值对象访问右值引用对象

C++类成员的静态成员变量被实例化两次

c++ - 跳过 C++ 模板参数

c++ - 用 nullptr 初始化

c++ - decltype(*this) 等效于外部函数体

c++ boost 库 - 写入 ini 文件而不覆盖?