views:

62

answers:

2

so you have a class employee

class employee {
public:
    employee(const string &name, int id) : m_name(name) , m_id(id) {}

    const string &getName() const { return m_name; }
    int getID() const { return m_id; }
private:
    string &m_name;
    int m_id;
};

and you have private data members for encapsulation. But now you want to use a boost::multi_index....

typedef multi_index_container <
    employee, 
    indexed_by<
        ordered_non_unique< 
            composite_key<
                Name,
                member< employee,  string & , &employee::m_name>,
                member< employee,  int, &employee::m_id>
            >
        >
      >
> employee_set;

so I could use BOOST_INDEX_CONST_MEM_FUN...

typedef multi_index_container <
        employee, 
        indexed_by<
            ordered_non_unique< 
                composite_key<
                    Name,
                    BOOST_MULTI_INDEX_CONST_MEM_FUN(employee, const string&, getName),
                    BOOST_MULTI_INDEX_CONST_MEM_FUN(employee, int, getID)
                >
            >
          >
    > employee_set;

but what I'd really like to do is to grant employee_set access to my employee class's private data members. I just can't figure out how to do it :-/

A: 

Forget about it. Boost can choose to access your object from anywhere in its internals, and friendship is never transitive, so there is no way to befriend an internal structure via an external one.

You might try putting those data members in a private base class. Then the "privileged" operation is extracting the base from employee, which can be done at the point of instantiation of mutli_index_container within your own code, no friends needed.

Or, just make them all public.

Potatoswatter
+1  A: 

If I'm understanding this correctly, it is actually the access to the pointer-to-member value &employee::m_name, used as the third template parameter to member<> within the employee_set typedef, that causes the access violation (i.e. compiler error). If that pointer value could be obtained, it would then be passed around within the Boost.MultiIndex code and could be invoked from wherever, and no access checks would need to be made. Now, I don't know how class employee could grand friendship to a top-level typedef (I think you can only grant friendship to classes and functions), but you could make the employee_set a public member of a new class, and grant friendship to that class:

class employee { 
  ...
  friend struct mytypedefs;
};

struct mytypedefs {
  typedef multi_index_container <
  ... &employee::m_name ...
  > employee_set;
};

int main() {
  mytypedefs::employee_set my_employee_set;
}
SCFrench
The pointer-to-member, not a pointer resulting from it, needs to be stored and passed around in the multi_index templates.
Potatoswatter
Not really, that particular template parameter is a non-type parameter, so it's embedded in the type of the member<> template instantiation.
SCFrench
Or you could just provide the employee_set typedef directly in employee
Anthony Williams