如何仅使用活页夹在地图中查找值

发布于 2024-08-11 01:39:11 字数 594 浏览 1 评论 0 原文

在地图的第二个值中搜索,我使用如下内容:

typedef std::map<int, int> CMyList;
static CMyList myList;

template<class t> struct second_equal
{
    typename typedef t::mapped_type mapped_type;
    typename typedef t::value_type value_type;

    second_equal(mapped_type f) : v(f)   {};
    bool operator()(const value_type &a) { return a.second == v;};

    mapped_type v;
};
...    
int i = 7;
CMyList::iterator it = std::find_if(myList.begin(), myList.end(), 
                                    second_equal<CMyList>(i));

问题:如何在不提供自写模板的情况下在一行中进行这样的查找?

Searching in the second value of a map i use somthing like the following:

typedef std::map<int, int> CMyList;
static CMyList myList;

template<class t> struct second_equal
{
    typename typedef t::mapped_type mapped_type;
    typename typedef t::value_type value_type;

    second_equal(mapped_type f) : v(f)   {};
    bool operator()(const value_type &a) { return a.second == v;};

    mapped_type v;
};
...    
int i = 7;
CMyList::iterator it = std::find_if(myList.begin(), myList.end(), 
                                    second_equal<CMyList>(i));

Question: How can i do such a find in a single line without supplying a self written template?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

桃扇骨 2024-08-18 01:39:11

使用选择器从映射中获取的 value_type 选择第一个或第二个元素。
使用绑定器将值 (i) 绑定到 std::equal_to 函数的参数之一。
使用组合器将选择器的输出用作 equal_to 函数的另一个参数。

//stl version
CMyList::iterator it = std::find_if(
    myList.begin(), 
    myList.end(), 
    std::compose1(
        std::bind2nd(equal_to<CMyList::mapped_type>(), i), 
        std::select2nd<CMyList::value_type>())) ;

//Boost.Lambda or Boost.Bind version
CMyList::iterator it = std::find_if(
    myList.begin(), 
    myList.end(), 
    bind( &CMyList::mapped_type::second, _1)==i);

Use a selector to select the first or the second element from the value_type that you get from the map.
Use a binder to bind the value (i) to one of the arguments of the std::equal_to function.
Use a composer to use the output of the selector as the other argument of the equal_to function.

//stl version
CMyList::iterator it = std::find_if(
    myList.begin(), 
    myList.end(), 
    std::compose1(
        std::bind2nd(equal_to<CMyList::mapped_type>(), i), 
        std::select2nd<CMyList::value_type>())) ;

//Boost.Lambda or Boost.Bind version
CMyList::iterator it = std::find_if(
    myList.begin(), 
    myList.end(), 
    bind( &CMyList::mapped_type::second, _1)==i);
我是男神闪亮亮 2024-08-18 01:39:11

我自愿离开。 lambda 的问题是(除了 C++0x)你目前实际上不能使用像 _.second 这样的东西。

就个人而言,我因此使用:

template <class Second>
class CompareSecond
{
public:
  CompareSecond(Second const& t) : m_ref(t) {} // actual impl use Boost.callparams
  template <class First>
  bool operator()(std::pair<First,Second> const& p) const { return p.second == m_ref; }
private:
  Second const& m_ref;
};

将其与: 结合起来,

template <class Second>
CompareSecond<Second> compare_second(Second const& t)
{
  return CompareSecond<Second>(t);
}

以获得自动类型推导。

这样我就可以写

CMyList::iterator it = std::find_if(myList.begin(), myList.end(), compare_second(i));

True,它不使用活页夹。

但至少,我的内容是可读且易于理解的,在我看来,这比巧妙的技巧更胜一筹。

注意
实际上,我已经将 STL 算法包装成完整的容器,所以它会是:(

 CMyList::iterator it = toolbox::find_if(myList, compare_second(i));

恕我直言)显然是在没有用于类型推断的 auto 关键字的情况下获得的可读性。

I am going to be off, voluntarily. The problem with lambda's is that (apart from C++0x) you cannot actually use something like _.second at the moment.

Personally, I thus use:

template <class Second>
class CompareSecond
{
public:
  CompareSecond(Second const& t) : m_ref(t) {} // actual impl use Boost.callparams
  template <class First>
  bool operator()(std::pair<First,Second> const& p) const { return p.second == m_ref; }
private:
  Second const& m_ref;
};

Which I combine with:

template <class Second>
CompareSecond<Second> compare_second(Second const& t)
{
  return CompareSecond<Second>(t);
}

In order to get automatic type deduction.

And this way I can just write

CMyList::iterator it = std::find_if(myList.begin(), myList.end(), compare_second(i));

True, it does not use binders.

But at least, mine is readable and easily understandable, which beats the crap out of clever trickery in my opinion.

Note:
actually I went as far as wrapping STL algorithms to take full containers, so it would be:

 CMyList::iterator it = toolbox::find_if(myList, compare_second(i));

which (imho) is clearly as readable as you can get without the auto keyword for type inference.

嗫嚅 2024-08-18 01:39:11

您可以使用 Boost Lambda

CMyList::iterator it = std::find_if(
      myList.begin(), myList.end(), 
      boost::lambda::bind(&CMyList::value_type::second, boost::lambda::_1) == i);

You can use Boost Lambda

CMyList::iterator it = std::find_if(
      myList.begin(), myList.end(), 
      boost::lambda::bind(&CMyList::value_type::second, boost::lambda::_1) == i);
两个我 2024-08-18 01:39:11

您可以扭转这个问题,只需编写自己的算法并使用它即可。这样你就不必编写大量的小函子了。

template <typename Iter, typename T>
Iter find_second(Iter first, Iter last, T value) {
    while (first != last) {
        if (first->second == value) {
            return first;
        }
        ++first;
    }
    return first;
}

注意这没有经过测试,甚至没有经过编译。

在我看来,用活页夹解决这个问题只是需要大量丑陋的代码。您真正需要的是一种新算法,因此只需添加该算法即可。话虽如此,我可能最终会实现类似 Matthieu M. 想出了。

You can turn this problem around and just write your own algorithm and use it instead. This way you are not stuck with writing lots of little functors.

template <typename Iter, typename T>
Iter find_second(Iter first, Iter last, T value) {
    while (first != last) {
        if (first->second == value) {
            return first;
        }
        ++first;
    }
    return first;
}

Note this isn't tested or even compiled.

It seems to me that solving this with binders is just asking for lots of ugly code. What you are really asking for is a new algorithm so just add the algorithm. With that said, I would probably end up implementing something like Matthieu M. came up with.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文