Currently using C 20, GCC 11.1.0
I'm trying to create a class method that returns a std::pair
of uint32_t
and a reference to a unique pointer. The unique pointer comes from a vector of unique pointers stored as a variable in the class. However, it keeps saying:
error: could not convert ‘std::make_pair(_T1&&, _T2&&) [with _T1 = unsigned int; _T2 = std::unique_ptr<Panel>&; typename std::__strip_reference_wrapper<typename std::decay<_Tp2>::type>::__type = std::unique_ptr<Panel>; typename std::decay<_Tp2>::type = std::decay<std::unique_ptr<Panel>&>::type; typename std::__strip_reference_wrapper<typename std::decay<_Tp>::type>::__type = unsigned int; typename std::decay<_Tp>::type = unsigned int]((* &((Screen*)this)->Screen::panels.std::vector<std::unique_ptr<Panel> >::emplace_back<>()))’ from ‘pair<[...],std::unique_ptr<Panel>>’ to ‘pair<[...],std::unique_ptr<Panel>&>’
67 | return std::make_pair<PanelID, Panel_Ptr&>(
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
| |
| pair<[...],std::unique_ptr<Panel>>
68 | std::move(panelID), panels.emplace_back());
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Screen
{
private:
using PanelID = uint32_t;
using Panel_Ptr = std::unique_ptr<Panel>;
std::vector<Panel_Ptr> panels {};
public:
std::pair<PanelID, Panel_Ptr&> foo()
{
PanelID panelID {static_cast<PanelID>(panels.size())};
return std::make_pair<PanelID, Panel_Ptr&>(
std::move(panelID), panels.emplace_back());
}
};
CodePudding user response:
std::make_pair()
will automatically decay any references given to it to their value types.
The deduced types
V1
andV2
arestd::decay<T1>::type
andstd::decay<T2>::type
(the usual type transformations applied to arguments of functions passed by value) unless application ofstd::decay
results instd::reference_wrapper<X>
for some typeX
, in which case the deduced type isX&
.
https://en.cppreference.com/w/cpp/utility/pair/make_pair
Remove your explicit instantiation of the type parameters of std::make_pair()
and wrap the emplace_back()
call with std::ref
:
return std::make_pair(
std::move(panelID),
std::ref(panels.emplace_back())
);
Alternatively, you can explicitly make the std::pair
:
return std::pair<PanelID, Panel_Ptr&>(
std::move(panelID),
panels.emplace_back()
);
Finally, to note on your code, you are calling std::move()
on your PanelID
type even though it is just an integer. std::move()
is useless in that scenario, so removing it entirely would make your code clearer.
Though, putting it on a separate line is still necessary due to the unspecified order of evaluation of arguments passed to functions. Good awareness of this fact.