2009-09-22 1 views
0

разбирать пару, то можно сделать следующийДоступ к вложенным парам

boost::bind(&std::pair::second, _1); // returns the value of a pair 

Что об использовании комбинации различных контейнеров, как можно получить вложенную пару?

Например, когда я хотел разделить вектор в элементы, содержащиеся в дополнительной карте и элементов, где не содержится в дополнительной карте, я использовал следующее:

typedef int DWORD; typedef std::pair<std::string, bool> user_info; 
typedef std::map<DWORD, user_info> USER_MAP; 
typedef std::vector<DWORD> VEC_STAFF; 
VEC_STAFF::iterator it = std::partition(
    Staff.begin(), Staff.end(), 
    (bind(&USER_MAP::find, m_Users, _1) != m_Users.end())); 

Теперь у меня есть вторая проблема - во время при запуске приложения статус bool user_info может измениться, а позже я хочу переразделить вектор с элементами, которые имеют статус bool true, а не просто содержатся в дополнительной карте.

Однако у меня есть проблема с доступом ко второму элементу вложенной пары.

Я пробовал следующее, но я не могу получить доступ к вложенной паре!

VEC_STAFF::const_iterator itCurEnd = partition(Staff.begin(), Staff.end(), 
    bind(&USER_MAP::value_type::second::second, 
    bind(&USER_MAP::find, &m_Users, _1)) == true); 

ответ

1

Синтаксис, который вы использовали, очевидно, не работает. Первый «:: второй» уже означает нестатический член, а не тип. Если у вас есть пара внутри пары вы, вероятно, придется использовать два связывания вызовов:

typedef std::pair< int, bool > foo_t; 
typedef std::pair< int, foo_t > bar_t; 
..... 

bind(&foo_t::second, bind(&bar_t::second, 
    bind(&USER_MAP::find, _1) 
)) 

(. Я не проверял это Может быть, это то, что вы хотите)

Но три уровня, если связать довольно бросая вызов, на мой взгляд.

Редактировать: Как насчет этого?

template<typename Iter, typename Return> 
struct deref_2nd_2nd : std::unary_function<Iter, Return> { 
    Return operator()(Iter const& it) const { 
     return (*it).second.second; 
    } 
}; 

..... 

bind(
    deref_2nd_2nd<USER_MAP::iterator,bool>(), 
    bind(&USER_MAP::find, _1) 
) 
+1

Как сказал Глен, это, вероятно, лучше, чтобы написать свой собственный класс как предикат. Из вашего кода неясно, что вы пытаетесь сделать. find возвращает итератор, который не является парой. (Dereferencing отсутствует) – sellibitze

+0

Справа я понял это позже. Но теперь я еще более смущен, чем раньше. При первом вызове разбить вызов bind возвращает итератор. Как вы говорите, поиск возвращается в итераторе, но его аргумент функции - это значение, а не итератор, так как разыгрывается векторный итератор? Я предполагаю, что я хочу разыменовать итератор, который приведет к паре, а затем я хочу сравнить вторую часть пары с истиной –

+0

Я не знаю, что именно вы хотите. Как насчет случаев, когда find возвращает итератор, который сравнивается с USER_MAP.end()? – sellibitze

4

Не уверен, что я следую за то, что там происходит, но, как правило, когда я начинаю нарваться проблемы с затруднительное отрекаюсь скандалить и реализовать функтор. Это может упростить ваше дело.

мне следующее намного легче читать, чем все, что возиться с несколькими уровнями привязок

template <class Arg> 
struct Whatever : public std::unary_function<Arg, bool> 
{ 
    bool operator()(const Arg &arg1) const { 
     //logic here 
    } 
}; 

Whatever<???> functor; 
std::partition(Staff.begin(), Staff.end(), functor); 
+0

Определенно. Привязка хорошо в простых случаях, а иногда boost :: tie может быть полезна, но когда синтаксис становится слишком волосатым, вместо этого напишите свой собственный функтор. – jalf

+0

+1 Для возврата назад попробуйте что-то немного другое. –