简体   繁体   中英

C++ inheritance error when creating memory allocators

I'm wondering why the following code does NOT work. The main idea behind it is as follows:

  1. I want to use my custom classes that inherits by std allocator and boost::interprocess::allocator respectively and I want to use them instead of the base allocators
  2. When I create a class MyStdAllocator, which inherits by std::allocator and use it instead of std::allocator (see variables x1 and x2) it works and gives no warning and no errors.
  3. When I create a class MyBoostAllocator, which inherits by boost::interprocess::allocator and use it instead of boost::interprocess:allocator (see variables y1 and y2) it does NOT work and gives me compilation errors listed on the bottom of this question.

Clould you please tell me, why such inheritance does not work and how to fix it?

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <iostream>

using namespace boost::interprocess;


template <typename _Tp>
class MyStdAllocator : public std::allocator<_Tp>
{
};


template<class T, class SegmentManager>
class MyBoostAllocator : public allocator<T, SegmentManager>
{
};



typedef std::allocator<int> std_allocator;
typedef MyStdAllocator<int> my_std_allocator;

typedef allocator       <int, managed_shared_memory::segment_manager> boost_allocator;
typedef MyBoostAllocator<int, managed_shared_memory::segment_manager> my_boost_allocator;


int main(int argc, char** argv) {

    struct shm_remove {
        shm_remove() {
            shared_memory_object::remove("MySharedMemory");
        }

        ~shm_remove() {
            shared_memory_object::remove("MySharedMemory");
        }
    } remover;

    managed_shared_memory segment(create_only,
            "MySharedMemory", //segment name
            65536);

    //Create an allocator that allocates ints from the managed segment
    allocator<int, managed_shared_memory::segment_manager>
            allocator_instance(segment.get_segment_manager());


    std_allocator *x1;
    x1 = new std_allocator();
    delete x1;

    my_std_allocator *x2;
    x2 = new my_std_allocator();
    delete x2;


    boost_allocator *y1;
    y1 = new boost_allocator(segment.get_segment_manager());
    delete y1;

    // following lines generate compilation errors:
    my_boost_allocator *y2;
    y2 = new my_boost_allocator(segment.get_segment_manager());
    delete y2;

    std::cout<<"its working!\n";

    return 0;

}

The compilation error is as follows:

../src/test.cpp:73:59: error: no matching function for call to ‘MyBoostAllocator<int, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >::MyBoostAllocator(boost::interprocess::ipcdetail::basic_managed_memory_impl<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index, 16ul>::segment_manager*)’
../src/test.cpp:73:59: note: candidates are:
../src/test.cpp:24:7: note: MyBoostAllocator<int, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >::MyBoostAllocator()
../src/test.cpp:24:7: note:   candidate expects 0 arguments, 1 provided
../src/test.cpp:24:7: note: MyBoostAllocator<int, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >::MyBoostAllocator(const MyBoostAllocator<int, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >&)
../src/test.cpp:24:7: note:   no known conversion for argument 1 from ‘boost::interprocess::ipcdetail::basic_managed_memory_impl<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index, 16ul>::segment_manager* {aka boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>*}’ to ‘const MyBoostAllocator<int, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >&’
make: *** [src/test.o] Error 1

This seems to be a "supported C++11" question. See

http://wiki.apache.org/stdcxx/C++0xCompilerSupport

for which compilers support which features.

Inheriting constructors is gnu4.8+ only.

When they are you still have to explicitly put in a using construct.

template<class T, class SegmentManager> 
class MyBoostAllocator : public allocator<T, SegmentManager> 
{ 
 public:
     using allocator<T, SegmentManager >::allocator;
};  

Until that is available, write the constructors in your derived class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM