如何编写适用于矢量或映射迭代器的自定义算法

时间:2012-08-16 18:50:01

标签: c++ stl map

我想编写自己的算法(实际上只是一个函数),它需要一系列迭代器。如果迭代器来自映射,我想使用数据(iterator-> second)值。如果迭代器像向量或列表一样“正常”,我只想使用解引用的迭代器值。

5 个答案:

答案 0 :(得分:5)

我认为,价值吸引力的想法就在这里,但你可以在没有c++11的情况下实现它,而且根本没有结构,只使用函数:

template <typename T> 
const T& get(const T& t)
{
    return t;
}

template <typename T, typename V>
const V& get(const std::pair<T,V>& t)
{
    return t.second;
}


int main()
{
    std::vector<int> v = {1};
    std::cout << get(*v.begin());

    std::cout << "\n----\n";

    std::map<int, std::string> m;
    m.insert(std::make_pair(0, "sss"));
    std::cout << get(*m.cbegin());
}

答案 1 :(得分:4)

您可以创建一个value-getter类来提取您感兴趣的值。请注意,如果您将pair存储在任何容器中(它会转换所有pair},则此方法不起作用s,无论是否在地图中)。我认为只接受“常规”迭代器是一种更清晰的方法,让调用者可以适当地转换映射迭代器(正如你的问题的评论中所建议的那样)。

template<typename T>
struct get {
  static auto val(const T& t) -> const T&
  {
    return t;
  }
};

template<typename U, typename V>
struct get<std::pair<U, V>> {
  static auto val(const std::pair<U, V>& p) -> const V&
  {
    return p.second;
  }
};

// use like
get<decltype(*iter)>::val(*iter);

便利功能可能如下:

template<class T>
auto getval(const T& t) -> decltype(get<T>::val(t))
{
  return get<T>::val(t);
}

答案 2 :(得分:3)

您可以根据输入重载该功能:

void foo(const std::vector<int>::iterator& it1, const std::vector<int>::iterator& it2) 
{
   //use *it
}
void foo(const std::map<int,int>::iterator& it1, const std::map<int,int>::iterator& it2)
{
   //use it->second
}

编辑:

我认为这是你能达到目标的最接近的地方:

template <typename T, typename X>
void foo(T const& x, X const& y)
{

}

template <typename T, typename S>
void foo(const typename std::map<T,S>::iterator& x, const typename std::map<T,S>::iterator& y)
{

}

int main()
{
    std::map<int,int> x;
    std::vector<int> y;
    foo(x.begin(), x.end()); //will call second version
    foo(y.begin(), y.end()); //will call first version
}

答案 3 :(得分:2)

一个特质应该可以解决问题。首先是类型推导助手:

template <typename Iter>
typename iter_value<Iter>::value_type & iter_deref(Iter it)
{
    return iter_value<Iter>::deref(it);
}

我们所需要的就是这样:

template <typename Iter>
class iter_value
{
    template <typename T> struct aux
    {
        typedef T type;
        static type & deref(Iter it) { return *it; }
    };
    template <typename U, typename V> struct aux<std::pair<U const, V>>
    {
        typedef V type;
        static type & deref(Iter it) { return it->second; }
    };

    typedef typename std::iterator_traits<Iter>::value_type type;

public:
    typedef typename aux<type>::type value_type;

    static value_type & deref(Iter it)
    {
        return aux<type>::deref(it);
    }
};

答案 4 :(得分:1)

您可以创建一个从迭代器中提取值的函数。然后你可以根据迭代器的类型重载它。您可以在算法中使用该功能。假设向量为ints且地图为string - &gt; int,它可能如下所示:

int getValue(const std::vector<int>::iterator& it)
{
    return *it;
}

int getValue(const std::map<std::string, int>::iterator& it)
{
    return it->second;
}

然后算法可以使用函数getValue()从迭代器中获取值。