The following code:
#include <tuple>
int main ()
{
auto f = [] () -> decltype (auto)
{
return std::get<0> (std::make_tuple (0));
};
return f ();
}
(Silently) generates code with undefined behaviour - the temporary rvalue returned by make_tuple is propagated through the std::get<> and through the decltype(auto) onto the return type. So it ends up returning a reference to a temporary that has gone out of scope. See it here http://ift.tt/2kRmCn1.
Now, you could argue that my use of decltype(auto) is at fault. But in my generic code (where the type of the tuple might be std::tuple<Foo &>) I don't want to always make a copy. I really do want to extract the exact value or reference from the tuple.
My feeling is that this overload of std::get is dangerous:
template< std::size_t I, class... Types >
constexpr std::tuple_element_t<I, tuple<Types...> >&&
get( tuple<Types...>&& t ) noexcept;
Whilst propagating lvalue references onto tuple elements is probably sensible, I don't think that holds for rvalue references.
I'm sure the standards committee thought this through very carefully, but can anyone explain to me why this was considered the best option?
Aucun commentaire:
Enregistrer un commentaire