0

I have a problem in const manipulation of my variables. I have simplified the problem into the following program:

#include <string>
#include <iostream>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>

using boost::multi_index::multi_index_container;
using boost::multi_index::ordered_non_unique;
using boost::multi_index::ordered_unique;
using boost::multi_index::indexed_by;
using boost::multi_index::member;
using boost::multi_index::sequenced;

struct employee_entry
{
   employee_entry( const std::string& first,
                   const std::string& last,
                   long id):
                   first_name_(first),
                   last_name_(last),
                   id_(id)
   {}
   std::string first_name_;
   std::string last_name_;
   long id_;
};


typedef multi_index_container<
employee_entry, indexed_by<
   ordered_unique<member<employee_entry, std::string , &employee_entry::first_name_> >
   , ordered_non_unique<member<employee_entry, std::string , &employee_entry::last_name_> >
   , ordered_non_unique<member<employee_entry, long , &employee_entry::id_> >
    ,sequenced<>
   >
> employee_set;

using boost::multi_index::nth_index;
using boost::multi_index::get;

typedef nth_index<employee_set, 0>::type first_name_view;

class A
{
private:
    employee_set m_employees;
public:
    first_name_view& get()
    {
        return m_employees.get<0>();
    }

};


int main()
{
    A *a = new A;
   first_name_view& fnv = a->get();

   fnv.insert(employee_entry("John", "Smith", 110));
   fnv.insert(employee_entry("John1", "Hunk", 97));

   const A *a1 = a;
   first_name_view& fdv = a1->get();

   for(first_name_view::iterator it = fdv.begin(), it_end(fdv.end()); it != it_end; ++it)
   {
      //....
   }
   return 0;
}

assuming variable a1 MUST be constant, I get compilation error as:

$ c++ dr2.cpp 
dr2.cpp: In function ‘int main()’:
dr2.cpp:66:35: error: passing ‘const A’ as ‘this’ argument of ‘first_name_view& A::get()’ discards qualifiers [-fpermissive]

I appreciate if you kindly help me solve the issue. Thanks you

rahman
  • 4,820
  • 16
  • 52
  • 86

2 Answers2

4

You need a const overload of the get() function, which you can call on a const object; it must return a const reference since it can only call the const overload of employee_set::get():

class A
{
private:
    employee_set m_employees;
public:
    first_name_view& get()
    {
        return m_employees.get<0>();
    }
    first_name_view const & get() const   //< Add this
    {
        return m_employees.get<0>();
    }
};

and then you need to use that to initialise a const reference:

first_name_view const & fdv = a1->get();
             // ^^^^^ add this
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
3

a1 is a constant pointer, but the method A:get() can potentially modify the object's contents, because the method isn't marked as const.

Add a const qualifier after the parameters list:

first_name_view& get() const
{
    return m_employees.get<0>();
}
Rafał Rawicki
  • 22,324
  • 5
  • 59
  • 79
  • @Rafael Rawichi, I jst did that and I got this error(actually on of my problems is that I can't read these errors: – rahman May 11 '12 at 05:02
  • $ c++ dr2.cpp dr2.cpp: In member function ‘first_name_view& A::get() const’: dr2.cpp:51:29: error: invalid initialization of reference of type ‘first_name_view& {aka boost::multi_index::detail::ordered_index, &employee_entry::first_name_>, std::less >, boost::multi_index::detail::nth_layer<1, employee_entry, boost::multi_index::indexed_by, &employee_entry::first_name_> >, – rahman May 11 '12 at 05:04
  • boost::multi_index::ordered_non_unique, &employee_entry::last_name_> >, boost::multi_index::ordered_non_unique >, boost::multi_index::sequenced<> >, std::allocator >, boost::mpl::vector0, – rahman May 11 '12 at 05:04
  • boost::multi_index::detail::ordered_unique_tag>&}’ from expression of type ‘const type {aka const boost::multi_index::detail::ordered_index, &employee_entry::first_name_>, std::less >, boost::multi_index::detail::nth_layer<1, employee_entry, – rahman May 11 '12 at 05:05
  • boost::multi_index::indexed_by, &employee_entry::first_name_> >, boost::multi_index::ordered_non_unique, &employee_entry::last_name_> >, boost::multi_index::ordered_non_unique >, boost::multi_index::sequenced<> >, std::allocator >, – rahman May 11 '12 at 05:05
  • boost::mpl::vector0, boost::multi_index::detail::ordered_unique_tag>}’ – rahman May 11 '12 at 05:06
  • OMG, so much text, you could use a pastebin for that. That is another, completely different error. My answer solved the problem stated in the original question. – Rafał Rawicki May 11 '12 at 05:07
  • You need more constness: `first_name_view const & get() const`. – Mike Seymour May 11 '12 at 05:10
  • :) pastebin? what is that. Ok i will find out what pastebin is, but as with the problem, i guess it is the reference right? if yes, then my problem is the usage of reference and cost together. right?can you help me with that too? – rahman May 11 '12 at 05:10
  • @MikeSeymour rafael is right. I checked that two. the above error message will be shown twice! – rahman May 11 '12 at 05:13
  • 2
    @rahman: Yes, that's just part of what you need. See my answer for the rest. – Mike Seymour May 11 '12 at 05:19
  • I don't think you can return non-const reference from const method, unless the underlying data is `mutable`. – juanchopanza May 11 '12 at 06:15