vendredi 6 mars 2020

Defining destructor of base class makes std::map::emplace fail

When I try to emplace an object which has a unique_ptr and a destructor into a map, I get a compiler error, shown below. However, when the object has no destructor defined, emplacement works just fine. What is going on?

How can I emplace an object which has a unique_ptr and a destructor defined into a map?

#include <map>
#include <iostream>
#include <string>

struct A {
    std::string name;
    std::unique_ptr<int> p;
    virtual ~A(){};  // comment out this line
    A(std::string n) : name(n) { }
};
int main()
{
    std::map<int, A> m;
    m.emplace(1, A("Name"));
    return 0;
}

I'm using Apple clang version 11.0.0 on OSX

Compiler Error

In file included from main.cpp:1:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/map:480:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__tree:16:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1826:31: error: no matching constructor for initialization of 'std::__1::pair<const int, B>'
            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
                              ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1718:18: note: in instantiation of function template specialization
      'std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<int, B>, void *> >::construct<std::__1::pair<const int, B>, int, B>' requested here
            {__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
                 ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1561:14: note: in instantiation of function template specialization
      'std::__1::allocator_traits<std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<int, B>, void *> > >::__construct<std::__1::pair<const int, B>,
      int, B>' requested here
            {__construct(__has_construct<allocator_type, _Tp*, _Args...>(),
             ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__tree:2212:20: note: in instantiation of function template specialization
      'std::__1::allocator_traits<std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<int, B>, void *> > >::construct<std::__1::pair<const int, B>,
      int, B>' requested here
    __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
                   ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__tree:2157:29: note: in instantiation of function template specialization
      'std::__1::__tree<std::__1::__value_type<int, B>, std::__1::__map_value_compare<int, std::__1::__value_type<int, B>, std::__1::less<int>, true>,
      std::__1::allocator<std::__1::__value_type<int, B> > >::__construct_node<int, B>' requested here
        __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
                            ^

... [similar error messages come here]

main.cpp:19:11: note: in instantiation of function template specialization 'std::__1::map<int, B, std::__1::less<int>, std::__1::allocator<std::__1::pair<const
      int, B> > >::emplace<int, B>' requested here
        m.emplace(1, B("Name"));
      ^

Aucun commentaire:

Enregistrer un commentaire