Извлечение члена пары в лямбда-выражения и шаблон typedef идиома - PullRequest
2 голосов
/ 23 марта 2010

У меня есть несколько сложных типов, поэтому я решил использовать хитрый трюк, чтобы иметь typedef для шаблонных типов.Тогда у меня есть класс some_container, который имеет контейнер в качестве члена.Контейнер - это вектор пар, состоящий из элемента и вектора.Я хочу написать алгоритм std :: find_if с лямбда-выражением, чтобы найти элемент, который имеет определенное значение.Чтобы получить значение, я должен сначала вызвать пару, а затем получить значение из элемента.Ниже моего std :: find_if есть нормальный цикл, который делает свое дело.Моя лямбда не компилируется.Как получить доступ к значению внутри элемента, который находится внутри пары?Я использую g ++ 4.4+ и VS 2010, и сейчас я хочу увеличить лямбду.

#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;
}

1 Ответ

1 голос
/ 23 марта 2010

Два выпуска.

То, что вы ищете (element<T>::value) - это , а не имя типа.

Однако, во-первых, вам понадобятся вложенные привязки: одна для доступа к _1.first и другая для доступа к value предыдущего.

Без определения типа:

  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
  );

Хотя это не выглядит особенно читабельным. Возможно, а) ждать C ++ 0x лямбда, б) написать специальный функтор для вызова find_if, в) просто выполнить ручной цикл.

...