I had the same question and ended up figuring it out by reading the multi_index.hpp
from eosio.cdt code and wanted to share my solution.
Instead of using auto, declare the type by using myindex::const_iterator
:
struct [[eosio::table]] _obj {
name key;
uint64_t primary_key() const { return key.value; }
};
typedef eosio::multi_index<name("myindex"), _obj> myindex;
void do_biz_stuff(myindex::const_iterator& o) { ... }
Additional Note
If you want to use modify
, erase
, or iterator_to
inside do_biz_stuff
you must be sure to pass the iterator by reference and also to pass the multi_index instance by reference. Otherwise you'll receive the errors like object passed to modify / erase / iterator_to is not in multi_index
or copy constructor of 'item_ptr' is implicitly deleted because field '_item' has a deleted copy constructor
void do_biz_stuff(myindex& idx, myindex::const_iterator& itr) {
idx.erase(itr);
}
Using with Secondary Index
Also I just ran into the usecase of using with secondary index.
Define template to pass types:
struct [[eosio::table]] _obj {
name key;
name secondary;
uint64_t primary_key() const { return key.value; }
uint64_t mysecondary() const { return secondary.value; }
};
typedef eosio::multi_index<
name("myindex"),
_obj,
indexed_by<name("mysecondary"), const_mem_fun<_obj, uint64_t, &_obj::mysecondary>>
> myindex;
template <typename idxT, typename itrT>
void do_biz_stuff(idxT& idx, itrT& itr) { ... }
Usage:
myindex myidx(_self, _self.value);
auto mySecIdx = myidx.get_index<name("mysecondary")>();
auto mySecItr = mySecIdx.lower_bound(name("testSecondaryKey"));
do_biz_stuff<decltype(mySecIdx), decltype(mySecItr)>(mySecIdx, mySecItr);