C++ Необязательная ОШИБКА: constexpr std::_Optional_payload‹_Tp, ‹anonymous›, ‹anonymous› › не может быть перегружен

Я пытаюсь использовать в своем шаблоне необязательно, но борюсь с ошибкой при компиляции.

Код следующий:

template<typename T>
std::optional<const Edge<T>&> Graph<T>::getEdge(unsigned long edgeId) const
{
    
    auto it = edgeSet.begin();
    for(it; it != edgeSet.end(); ++it){
        if(it->getId() == edgeId){
            return std::make_optional<const Edge<T>&>(*it);
        }
    }
    std::optional<const Edge<T>&> result;
    return result;
}

у меня есть googletest, который делает эту работу:

ASSERT_FALSE(graph.getEdge(2).has_value());

он должен вернуть false и пройти тест. Но моя проблема в компиляции. Компилятор выдает мне эту ошибку:

In file included from /usr/include/c++/7/bits/node_handle.h:39:0,
                 from /usr/include/c++/7/bits/stl_tree.h:72,
                 from /usr/include/c++/7/map:60,
                 from /usr/include/gtest/internal/gtest-internal.h:58,
                 from /usr/include/gtest/gtest.h:58,
                 from /home/codespace/workspace/CXXGraph/test/test1.cpp:1:
/usr/include/c++/7/optional: In instantiation of ‘struct std::_Optional_payload<const CXXGRAPH::Edge<int>&, true, true>’:
/usr/include/c++/7/optional:425:30:   required from ‘class std::_Optional_base<const CXXGRAPH::Edge<int>&>’
/usr/include/c++/7/optional:453:11:   required from ‘class std::optional<const CXXGRAPH::Edge<int>&>’
/home/codespace/workspace/CXXGraph/test/test1.cpp:52:5:   required from here
/usr/include/c++/7/optional:137:17: error: ‘constexpr std::_Optional_payload<_Tp, <anonymous>, <anonymous> >::_Optional_payload(std::_Optional_payload<_Tp, <anonymous>, <anonymous> >::__ctor_tag<bool>, _Tp&&) [with _Tp = const CXXGRAPH::Edge<int>&; bool <anonymous> = true; bool <anonymous> = true]’ cannot be overloaded
       constexpr _Optional_payload(__ctor_tag<bool>, _Tp&& __other)
                 ^~~~~~~~~~~~~~~~~
/usr/include/c++/7/optional:127:17: error: with ‘constexpr std::_Optional_payload<_Tp, <anonymous>, <anonymous> >::_Optional_payload(std::_Optional_payload<_Tp, <anonymous>, <anonymous> >::__ctor_tag<bool>, const _Tp&) [with _Tp = const CXXGRAPH::Edge<int>&; bool <anonymous> = true; bool <anonymous> = true]’
       constexpr _Optional_payload(__ctor_tag<bool>,
                 ^~~~~~~~~~~~~~~~~
/usr/include/c++/7/optional: In instantiation of ‘union std::_Optional_payload<const CXXGRAPH::Edge<int>&, true, true>::<unnamed>’:
/usr/include/c++/7/optional:160:7:   required from ‘struct std::_Optional_payload<const CXXGRAPH::Edge<int>&, true, true>’
/usr/include/c++/7/optional:425:30:   required from ‘class std::_Optional_base<const CXXGRAPH::Edge<int>&>’
/usr/include/c++/7/optional:453:11:   required from ‘class std::optional<const CXXGRAPH::Edge<int>&>’
/home/codespace/workspace/CXXGraph/test/test1.cpp:52:5:   required from here
/usr/include/c++/7/optional:162:24: error: non-static data member ‘std::_Optional_payload<const CXXGRAPH::Edge<int>&, true, true>::<unnamed union>::_M_payload’ in a union may not have reference type ‘std::_Optional_payload<const CXXGRAPH::Edge<int>&, true, true>::_Stored_type {aka const CXXGRAPH::Edge<int>&}’
           _Stored_type _M_payload;
                        ^~~~~~~~~~
/usr/include/c++/7/optional: In instantiation of ‘class std::optional<const CXXGRAPH::Edge<int>&>’:
/home/codespace/workspace/CXXGraph/test/test1.cpp:52:5:   required from here
/usr/include/c++/7/optional:467:7: error: static assertion failed: Invalid instantiation of optional<T>
       static_assert(__and_<__not_<is_same<remove_cv_t<_Tp>, nullopt_t>>,
       ^~~~~~~~~~~~~
/usr/include/c++/7/optional:692:7: error: forming pointer to reference type ‘const CXXGRAPH::Edge<int>&’
       operator->() const
       ^~~~~~~~
/usr/include/c++/7/optional:696:7: error: forming pointer to reference type ‘const CXXGRAPH::Edge<int>&’
       operator->()
       ^~~~~~~~
/usr/include/c++/7/optional: In instantiation of ‘void std::_Optional_base<_Tp>::_M_construct(_Args&& ...) [with _Args = {CXXGRAPH::Edge<int>}; _Tp = const CXXGRAPH::Edge<int>&]’:
/usr/include/c++/7/optional:652:4:   required from ‘std::enable_if_t<std::is_constructible<_Tp, _Args&& ...>::value, _Tp&> std::optional<_Tp>::emplace(_Args&& ...) [with _Args = {CXXGRAPH::Edge<int>}; _Tp = const CXXGRAPH::Edge<int>&; std::enable_if_t<std::is_constructible<_Tp, _Args&& ...>::value, _Tp&> = const CXXGRAPH::Edge<int>&]’
/usr/include/c++/7/optional:540:11:   required from ‘constexpr std::optional<_Tp>::optional(std::optional<_Up>&&) [with _Up = CXXGRAPH::Edge<int>; typename std::enable_if<std::__and_<std::__not_<std::is_same<_T1, _U1> >, std::is_constructible<_Tp, _Up&&>, std::is_convertible<_Up&&, _Tp>, std::__not_<std::__or_<std::is_constructible<_Tp, const std::optional<_Up>&>, std::is_constructible<_Tp, std::optional<_Up>&>, std::is_constructible<_Tp, const std::optional<_Up>&&>, std::is_constructible<_Tp, std::optional<_Up>&&>, std::is_convertible<const std::optional<_Up>&, _Tp>, std::is_convertible<std::optional<_Up>&, _Tp>, std::is_convertible<const std::optional<_Up>&&, _Tp>, std::is_convertible<std::optional<_Up>&&, _Tp> > > >::value, bool>::type <anonymous> = 1; _Tp = const CXXGRAPH::Edge<int>&]’
/home/codespace/workspace/CXXGraph/include/Graph.hpp:176:49:   required from ‘std::optional<const CXXGRAPH::Edge<T>&> CXXGRAPH::Graph<T>::getEdge(long unsigned int) const [with T = int]’
/home/codespace/workspace/CXXGraph/test/test1.cpp:52:5:   required from here
/usr/include/c++/7/optional:404:11: error: new cannot be applied to a reference type
           ::new (std::__addressof(this->_M_payload._M_payload))
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             _Stored_type(std::forward<_Args>(__args)...);
             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/7/optional:404:34: error: invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
           ::new (std::__addressof(this->_M_payload._M_payload))
                  ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/bits/exception_ptr.h:40:0,
                 from /usr/include/c++/7/exception:142,
                 from /usr/include/c++/7/ios:39,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/gtest/gtest.h:55,
                 from /home/codespace/workspace/CXXGraph/test/test1.cpp:1:
/usr/include/c++/7/new:168:14: note:   initializing argument 2 of ‘void* operator new(std::size_t, void*)’
 inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
              ^~~~~~~~
In file included from /usr/include/c++/7/bits/node_handle.h:39:0,
                 from /usr/include/c++/7/bits/stl_tree.h:72,
                 from /usr/include/c++/7/map:60,
                 from /usr/include/gtest/internal/gtest-internal.h:58,
                 from /usr/include/gtest/gtest.h:58,
                 from /home/codespace/workspace/CXXGraph/test/test1.cpp:1:
/usr/include/c++/7/optional: In instantiation of ‘void std::_Optional_base<_Tp>::_M_destruct() [with _Tp = const CXXGRAPH::Edge<int>&]’:
/usr/include/c++/7/optional:421:17:   required from ‘void std::_Optional_base<_Tp>::_M_reset() [with _Tp = const CXXGRAPH::Edge<int>&]’
/usr/include/c++/7/optional:651:4:   required from ‘std::enable_if_t<std::is_constructible<_Tp, _Args&& ...>::value, _Tp&> std::optional<_Tp>::emplace(_Args&& ...) [with _Args = {CXXGRAPH::Edge<int>}; _Tp = const CXXGRAPH::Edge<int>&; std::enable_if_t<std::is_constructible<_Tp, _Args&& ...>::value, _Tp&> = const CXXGRAPH::Edge<int>&]’
/usr/include/c++/7/optional:540:11:   required from ‘constexpr std::optional<_Tp>::optional(std::optional<_Up>&&) [with _Up = CXXGRAPH::Edge<int>; typename std::enable_if<std::__and_<std::__not_<std::is_same<_T1, _U1> >, std::is_constructible<_Tp, _Up&&>, std::is_convertible<_Up&&, _Tp>, std::__not_<std::__or_<std::is_constructible<_Tp, const std::optional<_Up>&>, std::is_constructible<_Tp, std::optional<_Up>&>, std::is_constructible<_Tp, const std::optional<_Up>&&>, std::is_constructible<_Tp, std::optional<_Up>&&>, std::is_convertible<const std::optional<_Up>&, _Tp>, std::is_convertible<std::optional<_Up>&, _Tp>, std::is_convertible<const std::optional<_Up>&&, _Tp>, std::is_convertible<std::optional<_Up>&&, _Tp> > > >::value, bool>::type <anonymous> = 1; _Tp = const CXXGRAPH::Edge<int>&]’
/home/codespace/workspace/CXXGraph/include/Graph.hpp:176:49:   required from ‘std::optional<const CXXGRAPH::Edge<T>&> CXXGRAPH::Graph<T>::getEdge(long unsigned int) const [with T = int]’
/home/codespace/workspace/CXXGraph/test/test1.cpp:52:5:   required from here
/usr/include/c++/7/optional:413:38: error: the type being destroyed is ‘CXXGRAPH::Edge<int>’, but the destructor refers to ‘std::_Optional_base<const CXXGRAPH::Edge<int>&>::_Stored_type {aka const CXXGRAPH::Edge<int>&’
         this->_M_payload._M_payload.~_Stored_type();
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~
CMakeFiles/test_exe.dir/build.make:86: recipe for target 'CMakeFiles/test_exe.dir/test/test1.cpp.o' failed
make[2]: *** [CMakeFiles/test_exe.dir/test/test1.cpp.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/test_exe.dir/all' failed
make[1]: *** [CMakeFiles/test_exe.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

Я не знаю, где я ошибаюсь, я пробовал разные решения, но ни одно не работает. Кто-нибудь знает, что происходит? что не так в этом фрагменте кода? Есть что-то, что я пропустил при использовании необязательного?


person Zig Razor    schedule 12.10.2020    source источник
comment
На первый взгляд, std::optional<const Edge<T>&> описывает необязательную ссылку. Это в основном указатель, нет? Необязательный семантически предназначен либо ничего не содержать, либо значение (возможно, через смарт-указатель).   -  person dfrib    schedule 12.10.2020