По какой-то причине у меня есть несоответствие типов между итератором, возвращаемым функцией find (), и реализацией modify (), которую я использую для работы с ним. Мой код здесь и дословно воспроизведен здесь:
#include <iostream>
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/mem_fun.hpp>
class Placeholder {
public:
const uint64_t& getPlaceholderTime( void ) const { return ph_time; }
const std::string& getPlaceholderId( void ) const { return ph_id; }
void setNewId( std::string& newId ) { ph_id = newId; }
void setNewTime( uint64_t newTime ) { ph_time = newTime; }
private:
mutable uint64_t ph_time;
std::string ph_id;
};
struct IndexByPlaceholderId { };
typedef boost::multi_index_container<
Placeholder,
boost::multi_index::indexed_by
<boost::multi_index::ordered_non_unique< boost::multi_index::identity<Placeholder> >
,boost::multi_index::ordered_non_unique<
boost::multi_index::const_mem_fun<
Placeholder,
const uint64_t&,
&Placeholder::getPlaceholderTime
>
>
,boost::multi_index::ordered_non_unique<
boost::multi_index::tag<IndexByPlaceholderId>,
boost::multi_index::const_mem_fun<
Placeholder,
const std::string&,
&Placeholder::getPlaceholderId
>
>
>
> currentPlaceholderDatabase;
struct handlePlaceholderTransition {
handlePlaceholderTransition( std::string& newId, uint64_t newTime )
: newId_(newId)
, newTime_(newTime)
{
std::cout << "NewId: " << newId << std::endl;
std::cout << "NewTime: " << newTime << std::endl;
}
void operator()(Placeholder& ph)
{
ph.setNewId( newId_ );
ph.setNewTime( newTime_ );
}
private:
std::string newId_;
uint64_t newTime_;
};
void lambdaHandlePlaceholderTransition( Placeholder& ph, std::string& newId, uint64_t newTime )
{
ph.setNewId( newId );
ph.setNewTime( newTime );
}
int main()
{
static currentPlaceholderDatabase currentDb;
std::string someString = "something";
auto result = currentDb.get<IndexByPlaceholderId>().find( someString );
if( result == currentDb.get<IndexByPlaceholderId>().end() )
{
std::cout << "NOT FOUND\n";
}
else
{
std::string newUpdatedId = "NEW_ID";
currentDb.modify( result, handlePlaceholderTransition( newUpdatedId, 0 ) );
/*
currentDb.modify( result, [](Placeholder& ph) {
std::cout << "Modifying Placeholder\n";
std::string newUpdatedId = "NEW_ID";
lambdaHandlePlaceholderTransition( ph, newUpdatedId, 0 );
});
*/
std::cout << "FOUND!!\n";
}
}
Это приводит к ошибке, когда кажется, что итератор обернут в два дополнительных слоя преобразования шаблона order_index_node (я не уверен соответствующего языка, чтобы описать это):
/usr/include/boost/multi_index/ordered_index.hpp:434:8: note: template argument deduction/substitution failed:
87:80: note:
cannot convert 'result' (type
'boost::multi_index::detail::bidir_node_iterator<
boost::multi_index::detail::ordered_index_node<
boost::multi_index::detail::index_node_base<
Placeholder,
std::allocator<Placeholder>
>
>
>')
для ввода '... base_type_of_container ... :: iterator
{aka
boost::multi_index::detail::bidir_node_iterator<
boost::multi_index::detail::ordered_index_node<
boost::multi_index::detail::ordered_index_node<
boost::multi_index::detail::ordered_index_node<
boost::multi_index::detail::index_node_base<
Placeholder,
std::allocator<Placeholder>
>
>
>
>
>}'
он также показывает, что эти типы похожи, за исключением дополнительные «уровни» упаковки шаблона. Этот пример основан на примере, показанном в документации MultiIndex при сравнении изменения с заменой, поэтому я затрудняюсь объяснить это.
Мои вопросы :
1.) Каков правильный синтаксис для передачи этого функтора, чтобы он успешно компилировался с использованием c ++ 11 и
2.) Могу ли я заменить функтор на эту лямбду, которая должна делать тоже самое? Я попытался заменить строку currentDb.modify () на этот фрагмент кода (как показано в комментариях выше), но получил ту же ошибку:
currentDb.modify( result, [](Placeholder& ph) {
std::cout << "Modifying Placeholder\n";
std::string newUpdatedId = "NEW_ID";
lambdaHandlePlaceholderTransition( ph, newUpdatedId, 0 );
});