在 lambda 表达式和模板 typedef 习惯用法中提取对成员

发布于 2024-08-26 12:08:18 字数 1734 浏览 7 评论 0原文

我这里有一些复杂的类型,所以我决定使用漂亮的技巧在模板化类型上使用 typedef。然后我有一个类 some_container ,它有一个容器作为成员。容器是由元素和向量组成的对的向量。我想用 lambda 表达式编写 std::find_if 算法来查找具有特定值的元素。为了获取值,我必须首先调用pair,然后从元素中获取值。在我的 std::find_if 下面有一个正常的循环可以解决这个问题。我的 lambda 无法编译。如何访问对内元素内的值? 我使用 g++ 4.4+ 和 VS 2010,现在我想坚持使用 boost lambda。

#include <vector>
#include <algorithm>
#include <boost\lambda\lambda.hpp>
#include <boost\lambda\bind.hpp>

template<typename T>
class element
{
public:
   T value;
};

template<typename T>
class element_vector_pair // idiom to have templated typedef
{
public:
   typedef std::pair<element<T>, std::vector<T> > type;
};

template<typename T>
class vector_containter // idiom to have templated typedef
{
public:
   typedef std::vector<typename element_vector_pair<T>::type > type;
};

template<typename T>
bool operator==(const typename element_vector_pair<T>::type & lhs, const typename element_vector_pair<T>::type & rhs)
{
   return lhs.first.value == rhs.first.value;
}

template<typename T>
class some_container
{
public:
   element<T> get_element(const T& value) const
   {
      std::find_if(container.begin(), container.end(), bind(&typename vector_containter<T>::type::value_type::first::value, boost::lambda::_1) == value);
      /*for(size_t i = 0; i < container.size(); ++i)
      {
      if(container.at(i).first.value == value)
      {
      return container.at(i);
      }
      }*/
      return element<T>(); //whatever
   }

protected:
   typename vector_containter<T>::type container;
};

int main()
{
   some_container<int> s;
   s.get_element(5);
   return 0;
}

I have some complex types here so I decided to use nifty trick to have typedef on templated types. Then I have a class some_container that has a container as a member. Container is a vector of pairs composed of element and vector. I want to write std::find_if algorithm with lambda expression to find element that have certain value. To get the value I have to call first on pair and then get value from element. Below my std::find_if there is normal loop that does the trick. My lambda fails to compile. How to access value inside element which is inside pair?
I use g++ 4.4+ and VS 2010 and I want to stick to boost lambda for now.

#include <vector>
#include <algorithm>
#include <boost\lambda\lambda.hpp>
#include <boost\lambda\bind.hpp>

template<typename T>
class element
{
public:
   T value;
};

template<typename T>
class element_vector_pair // idiom to have templated typedef
{
public:
   typedef std::pair<element<T>, std::vector<T> > type;
};

template<typename T>
class vector_containter // idiom to have templated typedef
{
public:
   typedef std::vector<typename element_vector_pair<T>::type > type;
};

template<typename T>
bool operator==(const typename element_vector_pair<T>::type & lhs, const typename element_vector_pair<T>::type & rhs)
{
   return lhs.first.value == rhs.first.value;
}

template<typename T>
class some_container
{
public:
   element<T> get_element(const T& value) const
   {
      std::find_if(container.begin(), container.end(), bind(&typename vector_containter<T>::type::value_type::first::value, boost::lambda::_1) == value);
      /*for(size_t i = 0; i < container.size(); ++i)
      {
      if(container.at(i).first.value == value)
      {
      return container.at(i);
      }
      }*/
      return element<T>(); //whatever
   }

protected:
   typename vector_containter<T>::type container;
};

int main()
{
   some_container<int> s;
   s.get_element(5);
   return 0;
}

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

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

发布评论

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

评论(1

锦上情书 2024-09-02 12:08:19

两个问题。

您要追求的东西(element::value不是类型名称。

但是,首先您需要嵌套绑定:一个用于访问 _1.first,另一个用于访问前一个的 value

没有 typedef:

  std::find_if(
    container.begin(), container.end(),
    bind(
      &element<T>::value,
      bind(&std::pair<element<T>, std::vector<T> >::first, boost::lambda::_1)
    ) == value
  ); 

所以,用你的习惯用法,没有不必要的 typename

  std::find_if( container.begin(), container.end(),
    bind(
      &vector_containter<T>::type::value_type::first_type::value,
      bind(
         &vector_containter<T>::type::value_type::first, boost::lambda::_1)
      ) == value
  );

不过,这似乎不是特别可读。也许 a) 等待 C++0x lambda,b) 为 find_if 调用编写一个特定的函子,c) 只需执行手动循环。

Two issues.

The thing that you are going after (element<T>::value) is not a typename.

However, firstly you'll need nested binds: one to access _1.first and another one to access the value of the previous.

Without the typedefs:

  std::find_if(
    container.begin(), container.end(),
    bind(
      &element<T>::value,
      bind(&std::pair<element<T>, std::vector<T> >::first, boost::lambda::_1)
    ) == value
  ); 

And so, with your idiom, without the unnecessary typename:

  std::find_if( container.begin(), container.end(),
    bind(
      &vector_containter<T>::type::value_type::first_type::value,
      bind(
         &vector_containter<T>::type::value_type::first, boost::lambda::_1)
      ) == value
  );

This doesn't seem particularly readable, though. Perhaps a) wait for C++0x lambda, b) write a specific functor for the find_if call, c) just do a manual loop.

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