Note that there are some explanatory texts on larger screens.

plurals
  1. POPartial string search in boost::multi_index_container
    primarykey
    data
    text
    <p>I have a struct to store info about persons and multi_index_contaider to store such objects. Mult-index uses for search by different criteria.</p> <p>I've added several persons into container and want to find person by lastname. It works great, if I use whole lastname. But it returns nothig if I try to find person by a part of a lastname (first letters of a lastname).</p> <p>As you know, partial string search works as a charm for <code>std::set&lt;string</code>>. So I've only wraped strings by a struct and lost that functionality.</p> <p>Here is compilable code:</p> <pre><code>#include &lt;iostream&gt; #include &lt;string&gt; #include &lt;algorithm&gt; #include &lt;set&gt; #include &lt;boost/multi_index_container.hpp&gt; #include &lt;boost/multi_index/ordered_index.hpp&gt; #include &lt;boost/multi_index/identity.hpp&gt; #include &lt;boost/multi_index/member.hpp&gt; #include &lt;boost/multi_index/composite_key.hpp&gt; #define DEFAULT_ADDRESS "Moscow" #define DEFAULT_PHONE "11223344" typedef unsigned int uint; using namespace boost; using namespace boost::multi_index; struct person { std::string m_first_name; std::string m_last_name; std::string m_third_name; std::string m_address; std::string m_phone; person(); person(std::string f, std::string l, std::string t = "", std::string a = DEFAULT_ADDRESS, std::string p = DEFAULT_PHONE) : m_first_name(f), m_last_name(l), m_third_name(t), m_address(a), m_phone(p) { } virtual ~person() { /*std::cout &lt;&lt; "Destructing person..." &lt;&lt; std::endl;*/ } person&amp; operator=(const person&amp; rhs); }; typedef multi_index_container&lt; person, indexed_by&lt; ordered_unique&lt;identity&lt;person&gt; &gt;, ordered_non_unique&lt; composite_key&lt; person, member&lt;person, std::string, &amp;person::m_last_name&gt;, member&lt;person, std::string, &amp;person::m_first_name&gt;, member&lt;person, std::string, &amp;person::m_third_name&gt; &gt; &gt; &gt; &gt; persons_set; person&amp; person::operator=(const person &amp;rhs) { m_first_name = rhs.m_first_name; m_last_name = rhs.m_last_name; m_third_name = rhs.m_third_name; m_address = rhs.m_address; m_phone = rhs.m_phone; return *this; } bool operator&lt;(const person &amp;lhs, const person &amp;rhs) { if(lhs.m_last_name == rhs.m_last_name) { if(lhs.m_first_name == rhs.m_first_name) return (lhs.m_third_name &lt; rhs.m_third_name); return (lhs.m_first_name &lt; rhs.m_first_name); } return (lhs.m_last_name &lt; rhs.m_last_name); } std::ostream&amp; operator&lt;&lt;(std::ostream &amp;s, const person &amp;rhs) { s &lt;&lt; "Person's last name: " &lt;&lt; rhs.m_last_name &lt;&lt; std::endl; s &lt;&lt; "Person's name: " &lt;&lt; rhs.m_first_name &lt;&lt; std::endl; if (!rhs.m_third_name.empty()) s &lt;&lt; "Person's third name: " &lt;&lt; rhs.m_third_name &lt;&lt; std::endl; s &lt;&lt; "Phone: " &lt;&lt; rhs.m_phone &lt;&lt; std::endl; s &lt;&lt; "Address: " &lt;&lt; rhs.m_address &lt;&lt; std::endl &lt;&lt; std::endl; return s; } struct comp_persons { bool operator()( const person&amp; p1, const person&amp; p2) const { if (p2.m_last_name.empty()) return false; return ( p1.m_last_name.find(p2.m_last_name) == 0 ); } }; int main() { persons_set my_set; persons_set::nth_index&lt;0&gt;::type &amp;general_index = my_set.get&lt;0&gt;(); // shortcut to the 1st index persons_set::nth_index&lt;1&gt;::type &amp;names_index = my_set.get&lt;1&gt;(); // shortcut to the 2nd index // adding persons general_index.insert(person("Alex", "Johnson", "Somename")); general_index.insert(person("Alex", "Goodspeed")); general_index.insert(person("Peter", "Goodspeed")); general_index.insert(person("Akira", "Kurosava")); // search via 2nd index (based on last_name) std::pair&lt;persons_set::nth_index&lt;1&gt;::type::const_iterator, persons_set::nth_index&lt;1&gt;::type::const_iterator&gt; n_it = names_index.equal_range("Goodspeed"); // this finds nothing /*std::pair&lt;persons_set::nth_index&lt;1&gt;::type::const_iterator, persons_set::nth_index&lt;1&gt;::type::const_iterator&gt; n_it = names_index.equal_range("Goodspe");*/ // idea by Kirill V. Lyadvinsky. This code crashes on the start. // I guess because behaviour of comp_persons differs from default less&lt;&gt; or reloaded operator &lt; /*std::pair&lt;persons_set::nth_index&lt;1&gt;::type::const_iterator, persons_set::nth_index&lt;1&gt;::type::const_iterator&gt; n_it = std::equal_range(names_index.begin(), names_index.end(), person("Alex", "Goodspe"), comp_persons());*/ std::copy( n_it.first ,n_it.second, std::ostream_iterator&lt;person&gt;(std::cout)); return 0; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload