c++boostfriendboost-ptr-container

C++ Befriending boost::ptr_map / boost::checked_delete fails


I want to use a boost::ptr_map inside a specific class which stores instances of itself. However, please consider the following example:

#include <boost/checked_delete.hpp>
#include <boost/ptr_container/ptr_map.hpp>


class foo
{
    friend void boost::checked_delete<>(foo*);
    ~foo() {}
};


int main()
{
    boost::checked_delete(new foo);     // OK
    boost::ptr_map<int, foo> foo_map;   // error C2248: 'foo::~foo' : cannot access private member declared in class 'foo'

    return 0;
}

The error happens at the following line

// verify that types are complete for increased safety

template<class T> inline void checked_delete(T * x)
{
    // intentionally complex - simplification causes regressions
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);
    delete x;    // error C2248
}

What exactly is going on here? Shouldn't it work? I assume that the problem is that templates are defined in the compilation unit they are included in and boost::checked_delete is called from another compilation unit in the implementation source of bosst::ptr_map. So, it's not the same function I declared as a friend.

However, is there a workaround for this problem?


Solution

  • Here is the start of the huge error message* from GCC, which is the start of the chain of instantiations (usually, and in this case):

    In file included from main.cpp:1:0: main.cpp: In function 'void boost::checked_delete(T*) [with T = const foo]':

    Adding

    friend void boost::checked_delete<>(foo const*);
    

    makes the code compile.

    (*): 13 lines and 3510 characters for 270 chars/line