Странная ошибка от перемещения и копирования конструкторов, которые имеют shared_ptrs - PullRequest
0 голосов
/ 30 марта 2019

Я получаю следующие ошибки при попытке скомпилировать мой класс HuffmanNode для назначения, похоже, это как-то связано с shared_ptrs в классе, но я понятия не имею, что на самом деле идет не так из-за явного количество текста, которое я не могу найти, чтобы найти реальную проблему.

g++ -std=c++11 -c src/HuffmanNode.cpp -o obj/HuffmanNode.o -I headers
In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
                 from /usr/include/c++/7/bits/allocator.h:46,
                 from /usr/include/c++/7/memory:63,
                 from headers/HuffmanNode.hpp:9,
                 from src/HuffmanNode.cpp:5:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = FLNRHE001::HuffmanNode; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode]’:
/usr/include/c++/7/bits/alloc_traits.h:475:4:   required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = FLNRHE001::HuffmanNode; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<FLNRHE001::HuffmanNode>]’
/usr/include/c++/7/bits/shared_ptr_base.h:526:39:   required from ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:637:4:   required from ‘std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:1295:35:   required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr.h:344:64:   required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode]’
/usr/include/c++/7/bits/shared_ptr.h:690:14:   required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}]’
/usr/include/c++/7/bits/shared_ptr.h:706:39:   required from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}]’
src/HuffmanNode.cpp:34:72:   required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: no matching function for call to ‘FLNRHE001::HuffmanNode::HuffmanNode(const std::shared_ptr<FLNRHE001::HuffmanNode>&)’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/HuffmanNode.cpp:41:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(FLNRHE001::HuffmanNode&&)
 HuffmanNode::HuffmanNode(HuffmanNode &&n)
 ^~~~~~~~~~~
src/HuffmanNode.cpp:41:1: note:   no known conversion for argument 1 from ‘const std::shared_ptr<FLNRHE001::HuffmanNode>’ to ‘FLNRHE001::HuffmanNode&&’
src/HuffmanNode.cpp:33:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(const FLNRHE001::HuffmanNode&)
 HuffmanNode::HuffmanNode(const HuffmanNode &n)
 ^~~~~~~~~~~
src/HuffmanNode.cpp:33:1: note:   no known conversion for argument 1 from ‘const std::shared_ptr<FLNRHE001::HuffmanNode>’ to ‘const FLNRHE001::HuffmanNode&’
src/HuffmanNode.cpp:11:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(char, int, std::shared_ptr<FLNRHE001::HuffmanNode>, std::shared_ptr<FLNRHE001::HuffmanNode>)
 HuffmanNode::HuffmanNode(char c, int f, std::shared_ptr<HuffmanNode> l, std::shared_ptr<HuffmanNode> r)
 ^~~~~~~~~~~
src/HuffmanNode.cpp:11:1: note:   candidate expects 4 arguments, 1 provided
In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
                 from /usr/include/c++/7/bits/allocator.h:46,
                 from /usr/include/c++/7/memory:63,
                 from headers/HuffmanNode.hpp:9,
                 from src/HuffmanNode.cpp:5:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = FLNRHE001::HuffmanNode; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp
= FLNRHE001::HuffmanNode]’:
/usr/include/c++/7/bits/alloc_traits.h:475:4:   required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = FLNRHE001::HuffmanNode; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<FLNRHE001::HuffmanNode>]’
/usr/include/c++/7/bits/shared_ptr_base.h:526:39:   required from ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&};
_Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:637:4:   required from ‘std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:1295:35:   required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr.h:344:64:   required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode]’
/usr/include/c++/7/bits/shared_ptr.h:690:14:   required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}]’
/usr/include/c++/7/bits/shared_ptr.h:706:39:   required from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}]’
src/HuffmanNode.cpp:93:52:   required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: no matching function for call to ‘FLNRHE001::HuffmanNode::HuffmanNode(std::shared_ptr<FLNRHE001::HuffmanNode>&)’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/HuffmanNode.cpp:41:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(FLNRHE001::HuffmanNode&&)
 HuffmanNode::HuffmanNode(HuffmanNode &&n)
 ^~~~~~~~~~~
src/HuffmanNode.cpp:41:1: note:   no known conversion for argument 1 from ‘std::shared_ptr<FLNRHE001::HuffmanNode>’ to ‘FLNRHE001::HuffmanNode&&’
src/HuffmanNode.cpp:33:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(const FLNRHE001::HuffmanNode&)
 HuffmanNode::HuffmanNode(const HuffmanNode &n)
 ^~~~~~~~~~~
src/HuffmanNode.cpp:33:1: note:   no known conversion for argument 1 from ‘std::shared_ptr<FLNRHE001::HuffmanNode>’ to ‘const FLNRHE001::HuffmanNode&’
src/HuffmanNode.cpp:11:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(char, int, std::shared_ptr<FLNRHE001::HuffmanNode>, std::shared_ptr<FLNRHE001::HuffmanNode>)
 HuffmanNode::HuffmanNode(char c, int f, std::shared_ptr<HuffmanNode> l, std::shared_ptr<HuffmanNode> r)
 ^~~~~~~~~~~
src/HuffmanNode.cpp:11:1: note:   candidate expects 4 arguments, 1 provided

Я пытался найти ошибки, но не могу найти ничего, что решило бы проблему.

Я не могу опубликовать весь свой код из-за того, что он является присваиванием, но строки, которые упоминаются в тексте ошибки, являются объявлениями моего конструктора, и, как указано выше, проблема, похоже, заключается в shared_ptrs:

line 11:    HuffmanNode::HuffmanNode(char c, int f,  std::shared_ptr<HuffmanNode> l, std::shared_ptr<HuffmanNode> r)

line 33:    HuffmanNode::HuffmanNode(const HuffmanNode &n) : ch(n.ch), freq(n.freq), left(std::make_shared<HuffmanNode>(n.left)), right(std::make_shared<HuffmanNode>(n.right))

line 41:    HuffmanNode::HuffmanNode(HuffmanNode &&n) : ch(std::move(n.ch)), freq(std::move(n.freq)), left(std::move(n.left)), right(std::move(n.right))

EDIT:

Вот что я могу опубликовать в соответствии со школьными правилами. Единственный метод, в котором есть контент проблемных областей, - это конструктор перемещения, который просто гарантирует, что при вызове деструктора не будет ошибок двойного удаления. , Это дает мне те же ошибки, что и выше.

#include <memory>

class HuffmanNode
{

    char ch;
    int freq;
    std::shared_ptr<HuffmanNode> left, right;

    // Node constructor for leaf node
    HuffmanNode(char c, int f, std::shared_ptr<HuffmanNode> l, std::shared_ptr<HuffmanNode> r)
        : ch(c), freq(f), left(l), right(r)
    {
        // Handled in initialiser list
    }

    HuffmanNode(const HuffmanNode &n)
        : ch(n.ch), freq(n.freq), left(std::make_shared<HuffmanNode>(n.left)),
          right(std::make_shared<HuffmanNode>(n.right))
    {
        // Handled by initialiser list
    }

    // Move Constructor
    HuffmanNode(HuffmanNode &&n)
        : ch(std::move(n.ch)), freq(std::move(n.freq)),
          left(std::move(n.left)),
          right(std::move(n.right))
    {
    }
};

1 Ответ

0 голосов
/ 30 марта 2019

Ошибки возникали при попытке использовать make_shared для создания копии левого и правого указателей, в этом случае мне требуется только поверхностное копирование, как это сделано конструктором копирования shared_ptr.

Исправленное решение было только изменением конструктора перемещения следующим образом:

HuffmanNode(const HuffmanNode &n)
        : ch(n.ch), freq(n.freq), left(n.left),
          right(n.right)
    {
        // Handled by initialiser list
    }

Спасибо Сэму Варшавчику за помощь в этом!

...