Incorrect return type from Gaudi::overload
With gcc13 I'm getting (in the LHCb Rec project) the warning
In file included from ../Rec/Tr/TrackMonitors/src/TrackVPOverlapMonitor.cpp:13:
../Rec/Tr/TrackFitEvent/include/Event/FitNode.h: In instantiation of 'R LHCb::FitNode::visit_r(Fs&& ...) const [with R = const ROOT::Math::SMatrix<double, 1, 5>&; Fs = {LHCb::Tr::Monitor::{anonymous}::projectionMatrix<LHCb::FitNode>(const LHCb::FitNode&)::<lambda(const DimInfos<LHCb::Enum::nDim::one, double>&)>, LHCb::Tr::Monitor::{anonymous}::projectionMatrix<LHCb::FitNode>(const LHCb::FitNode&)::<lambda(...)>}]':
../Rec/Tr/TrackMonitors/src/TrackVPOverlapMonitor.cpp:36:76: required from 'const Gaudi::TrackProjectionMatrix1D& LHCb::Tr::Monitor::{anonymous}::projectionMatrix(const TNode&) [with TNode = LHCb::FitNode; Gaudi::TrackProjectionMatrix1D = ROOT::Math::SMatrix<double, 1, 5>]'
../Rec/Tr/TrackMonitors/src/TrackVPOverlapMonitor.cpp:252:47: required from 'void LHCb::Tr::Monitor::TrackVPOverlapMonitor::fill(const LHCb::Track&, const TFitResult&) const [with TFitResult = LHCb::TrackFitResult; LHCb::Track = LHCb::Event::v1::Track]'
../Rec/Tr/TrackMonitors/src/TrackVPOverlapMonitor.cpp:145:27: required from here
../Rec/Tr/TrackFitEvent/include/Event/FitNode.h:560:9: warning: possibly dangling reference to a temporary [-Wdangling-reference]
560 | R r = static_cast<R>( std::visit( Gaudi::overload( std::forward<Fs>( fs )... ), m_dim ) );
| ^
../Rec/Tr/TrackFitEvent/include/Event/FitNode.h:560:39: note: the temporary was destroyed at the end of the full expression 'std::visit<Gaudi::details::overloaded_t<LHCb::Tr::Monitor::{anonymous}::projectionMatrix<LHCb::FitNode>(const LHCb::FitNode&)::<lambda(const LHCb::FitNode::DimInfos<LHCb::Enum::nDim::one, double>&)>, LHCb::Tr::Monitor::{anonymous}::projectionMatrix<LHCb::FitNode>(const LHCb::FitNode&)::<lambda(...)> >, const variant<LHCb::FitNode::DimInfos<LHCb::Enum::nDim::one, double>, LHCb::FitNode::DimInfos<LHCb::Enum::nDim::two, double> >&>(Gaudi::overload<LHCb::Tr::Monitor::{anonymous}::projectionMatrix<LHCb::FitNode>(const LHCb::FitNode&)::<lambda(const LHCb::FitNode::DimInfos<LHCb::Enum::nDim::one, double>&)>, LHCb::Tr::Monitor::{anonymous}::projectionMatrix<LHCb::FitNode>(const LHCb::FitNode&)::<lambda(...)> >((* & std::forward<LHCb::Tr::Monitor::{anonymous}::projectionMatrix<LHCb::FitNode>(const LHCb::FitNode&)::<lambda(const LHCb::FitNode::DimInfos<LHCb::Enum::nDim::one, double>&)> >((* & fs#0))), (* & std::forward<LHCb::Tr::Monitor::{anonymous}::projectionMatrix<LHCb::FitNode>(const LHCb::FitNode&)::<lambda(...)> >((* & fs#1)))), ((const LHCb::FitNode*)this)->LHCb::FitNode::m_dim)'
560 | R r = static_cast<R>( std::visit( Gaudi::overload( std::forward<Fs>( fs )... ), m_dim ) );
| ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I believe this comes from the fact that Gaudi::overload
is implemented as
auto overload( lambda_ts&&... lambdas ) {
which implies that even if we pass a lambda that returns T&
, Gaudi::overload
will return T
.
So the use of LHCb::FitNode::visit_r
(https://gitlab.cern.ch/lhcb/Rec/-/blob/8ddc2f832648097c1aff4f7b44875fbbb170f8cd/Tr/TrackFitEvent/include/Event/FitNode.h#L553) in https://gitlab.cern.ch/lhcb/Rec/-/blob/8ddc2f832648097c1aff4f7b44875fbbb170f8cd/Tr/TrackMonitors/src/TrackVPOverlapMonitor.cpp#L36-41 results in a call that returns a reference to a temporary object.
/cc @graven