2

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

4

5 回答 5

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());
}
于 2012-08-16T19:30:32.787 回答
4

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

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);
}
于 2012-08-16T19:00:52.753 回答
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
}
于 2012-08-16T18:52:17.743 回答
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);
    }
};
于 2012-08-16T19:19:11.463 回答
1

您可以创建一个从迭代器中提取值的函数。然后你可以根据迭代器的类型重载它。您可以在算法中使用该函数。假设->的向量ints和映射,它可能如下所示:stringint

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

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

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

于 2012-08-16T18:57:47.093 回答