具有 unique_ptr std 映射的单例类在编译时抛出错误

问题描述 投票:0回答:1

以下代码无法编译,我无法弄清楚为什么!


/* --------------------------------------------------------------- */
/* Includes */
#include <iostream>
#include <map>
#include <memory>
/* --------------------------------------------------------------- */

/* Forward delcarations */
class Person;
/* --------------------------------------------------------------- */

/* Using definitions */
using PersonUptr = std::unique_ptr<Person>;
/* --------------------------------------------------------------- */

/** @brief Person class to hold a record */
class Person {
public:
    /** @brief Explicit Ctor */
    explicit Person(const std::string& name)
                : m_name(name) {}

    /** @brief Person must stay unique */
    Person(const Person&) = delete;
    Person(Person&&) = delete;
    Person& operator=(const Person&) = delete;
    Person& operator=(Person&&) = delete;

    /** @virtual Dtor */
    virtual ~Person() =  default;

    /** @brief Return name/key */
    const std::string& getName(void) const {
        return m_name;
    }
private:
    /** @brief Class member variables */
    std::string m_name = "";
};

/** @brief Singleton container for storing Person instances */
class PersonContainer {
public:
    /** @brief Virtual Dtor */
    virtual ~PersonContainer() = default;

    /** @brief Delete copy/move */
    PersonContainer(const Person&) = delete;
    PersonContainer(Person&&) = delete;
    PersonContainer& operator=(const Person&) = delete;
    PersonContainer& operator=(Person&&) = delete;

    /** @brief Singleton instance */
    static PersonContainer& getInstance(void) {
        static PersonContainer container;
        return container;
    }

    /** @brief add Person unique ptr to map */
    void addPerson(PersonUptr&& person) {
        /** FIXME Check duplicate add */
        m_person_map.insert({person->getName(), std::move(person)});
    }
private:
    /** @brief Singleton private Ctor */
    PersonContainer() = default;

    /** @brief Class members */
    std::map<std::string, PersonUptr> m_person_map;
};

/** @brief Driver code */
int main(void) {

    /** Get container handle */
    auto handle = PersonContainer::getInstance();

    return 0;
}

错误:

In file included from personal-record.cc:4:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/iostream:43:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/ios:222:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__locale:15:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__memory/shared_ptr.h:22:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__memory/allocation_guard.h:15:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__memory/allocator_traits.h:304:9: error: no matching function for call to 'construct_at'
        _VSTD::construct_at(__p, _VSTD::forward<_Args>(__args)...);
        ^~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__config:897:17: note: expanded from macro '_VSTD'
\#  define _VSTD std
                ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__tree:2144:20: note: in instantiation of function template specialization 'std::allocator_traits<std::allocator<std::__tree_node<std::__value_type<std::string, std::unique_ptr<Person>>, void *>>>::construct<std::pair<const std::string, std::unique_ptr<Person>>, const std::pair<const std::string, std::unique_ptr<Person>> &, void, void>' requested here
    __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...);
                   ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__tree:2127:29: note: in instantiation of function template specialization 'std::__tree<std::__value_type<std::string, std::unique_ptr<Person>>, std::__map_value_compare<std::string, std::__value_type<std::string, std::unique_ptr<Person>>, std::less<std::string>>, std::allocator<std::__value_type<std::string, std::unique_ptr<Person>>>>::__construct_node<const std::pair<const std::string, std::unique_ptr<Person>> &>' requested here
        __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
                            ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__tree:1274:16: note: in instantiation of function template specialization 'std::__tree<std::__value_type<std::string, std::unique_ptr<Person>>, std::__map_value_compare<std::string, std::__value_type<std::string, std::unique_ptr<Person>>, std::less<std::string>>, std::allocator<std::__value_type<std::string, std::unique_ptr<Person>>>>::__emplace_hint_unique_key_args<std::string, const std::pair<const std::string, std::unique_ptr<Person>> &>' requested here
        return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v).first;
               ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/map:1318:29: note: in instantiation of member function 'std::__tree<std::__value_type<std::string, std::unique_ptr<Person>>, std::__map_value_compare<std::string, std::__value_type<std::string, std::unique_ptr<Person>>, std::less<std::string>>, std::allocator<std::__value_type<std::string, std::unique_ptr<Person>>>>::__insert_unique' requested here
            {return __tree_.__insert_unique(__p.__i_, __v);}
                            ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/map:1339:17: note: in instantiation of member function 'std::map<std::string, std::unique_ptr<Person>>::insert' requested here
                insert(__e.__i_, *__f);
                ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/map:1147:13: note: in instantiation of function template specialization 'std::map<std::string, std::unique_ptr<Person>>::insert<std::__map_const_iterator<std::__tree_const_iterator<std::__value_type<std::string, std::unique_ptr<Person>>, std::__tree_node<std::__value_type<std::string, std::unique_ptr<Person>>, void *> *, long>>>' requested here
            insert(__m.begin(), __m.end());
            ^
personal-record.cc:43:7: note: in instantiation of member function 'std::map<std::string, std::unique_ptr<Person>>::map' requested here
class PersonContainer {
      ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__memory/construct_at.h:39:38: note: candidate template ignored: substitution failure [with _Tp = std::pair<const std::string, std::unique_ptr<Person>>, _Args = <const std::pair<const std::string, std::unique_ptr<Person>> &>]: call to implicitly-deleted copy constructor of 'std::pair<const std::string, std::unique_ptr<Person>>'
_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&&... __args) {
                                     ^
1 error generated.
c++ singleton c++20 unique-ptr stdmap
1个回答
0
投票

在这一行中:

auto handle = PersonContainer::getInstance();

您尝试创建单例的副本,因为

auto
不会推断出引用。 您会收到错误,因为您的
map
包含
unique_ptr
,因此不可复制。

为了获得参考,您需要将其更改为:

//---v-----------------------------------------
auto & handle = PersonContainer::getInstance();
© www.soinside.com 2019 - 2024. All rights reserved.