c++ - std::map 的所有迭代器的模板特化

标签 c++ c++11 variadic-templates template-specialization typetraits

我有 traits 类,说:

template <class T>
struct KeyValueTraits
{
    typedef typename T::key_t key_t;
    typedef typename T::value_t value_t;
}

现在我想为 std::map 的所有迭代器声明此特征的特化

template < typename... Args >
struct KeyValueTraits<typename std::map<Args...>::iterator >
{
    typedef std::map<Args...> target_t;
    typedef typename target_t::key_type key_t;
    typedef typename target_t::mapped_type value_t;
};

编译器报错:

error C2764: 'Args': template parameter not used or deducible in partial specialization

那么如何为所有可能的 std::map<...>::iterator 声明特征类型?

最佳答案

您使用可变模板参数,所以我想您可以接受 C++11 解决方案。

我提出以下(不是很好)基于模板特化的解决方案。

std::map<>中考虑key的类型, 不是 key_t但是key_type并且值的类型不是 value_t但是mapped_type .

#include <map>

template <typename X>
struct with_kt
 { 
   template <typename Y = X>
   static constexpr bool getValue (int, typename Y::key_type * = nullptr)
    { return true; }

   static constexpr bool getValue (long)
    { return false; }

   static constexpr bool value { getValue(0) };
 };

template <typename T, bool = with_kt<T>::value>
struct KeyValueTraits;

template <typename T>
struct KeyValueTraits<T, true>
 {
   using key_t   = typename T::key_type;
   using value_t = typename T::mapped_type;
 };

template <typename T>
struct KeyValueTraits<T, false>
 {
   using pair_t  = decltype(* std::declval<T>());

   using key_t   = typename std::remove_const<
                      decltype(std::declval<pair_t>().first)>::type;
   using value_t = decltype(std::declval<pair_t>().second);
 };


using mil = std::map<int,long>;

int main()
 {
   static_assert(std::is_same<KeyValueTraits<mil>::key_t,
                              KeyValueTraits<mil::iterator>::key_t
                              >::value, "!");

   static_assert(std::is_same<KeyValueTraits<mil>::value_t,
                              KeyValueTraits<mil::iterator>::value_t
                              >::value, "!!");

   static_assert(std::is_same<KeyValueTraits<mil>::key_t,
                              KeyValueTraits<mil::const_iterator>::key_t
                              >::value, "!!!");

   static_assert(std::is_same<KeyValueTraits<mil>::key_t,
                              KeyValueTraits<mil::reverse_iterator>::key_t
                              >::value, "!!!!");

   static_assert(std::is_same<KeyValueTraits<mil>::key_t,
                              KeyValueTraits<mil::const_reverse_iterator>::key_t
                              >::value, "!!!!!");
 }

关于c++ - std::map 的所有迭代器的模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43161144/

相关文章:

c++ - 使用 std::initializer_list 初始化矩阵

c++ - 如何编写测试文件?

c++ - 多线程时使用 shared_ptr 进行写时复制

c++ - 具有静态绑定(bind)成员函数指针的可变参数模板的多个特化?

multithreading - SDL 和 C++11 线程

c++ - Variadic 可变模板模板,再次

c++ - 在可变参数模板类中初始化数组

c++ - 为什么 (*callback)() 有效,而 *callback() 或 *callback 在 C++ 中不起作用

c++ - 与数组一起使用时的双指针差异

c++ - 使用声明的可 rebase 类无法在 MSVC 中编译