Các mã sau đây:Hành vi của std :: có được trên các tham chiếu trị giá rvalue nguy hiểm không?
#include <tuple>
int main()
{
auto f = []() -> decltype (auto)
{
return std::get<0> (std::make_tuple (0));
};
return f();
}
(im lặng) tạo mã với hành vi không xác định - các rvalue tạm thời được trả về bởi make_tuple
được phổ biến qua std :: get <> và qua decltype (tự động) vào các kiểu trả về. Vì vậy, nó kết thúc trở lại một tham chiếu đến một tạm thời đã đi ra khỏi phạm vi. Xem tại đây https://godbolt.org/g/X1UhSw.
Bây giờ, bạn có thể cho rằng việc sử dụng decltype(auto)
của tôi là do lỗi. Nhưng trong mã chung của tôi (nơi mà loại tuple có thể là std::tuple<Foo &>
), tôi không muốn luôn tạo một bản sao. Tôi thực sự muốn trích xuất giá trị chính xác hoặc tham chiếu từ tuple.
Cảm giác của tôi là tình trạng quá tải này của std::get
là nguy hiểm:
template< std::size_t I, class... Types >
constexpr std::tuple_element_t<I, tuple<Types...> >&&
get(tuple<Types...>&& t) noexcept;
Trong khi tuyên truyền tài liệu tham khảo giá trị trái vào yếu tố tuple có lẽ là hợp lý, tôi không nghĩ rằng tổ chức để tham khảo rvalue.
Tôi chắc chắn rằng ủy ban tiêu chuẩn nghĩ điều này thông qua rất cẩn thận, nhưng bất cứ ai có thể giải thích cho tôi tại sao điều này được coi là lựa chọn tốt nhất?
* "Tôi không nghĩ rằng giữ cho tham chiếu rvalue" * - Nó sẽ xảy ra nếu bạn 'forward_as_tuple'. Bạn muốn danh mục giá trị được giữ nguyên. Hoặc nếu bạn muốn trích xuất một giá trị từ một hàm trả về giá trị. – StoryTeller
Cảm ơn, nhưng tôi không thực sự chắc chắn rằng nó đang bảo tồn danh mục giá trị. Ví dụ, nếu tôi có một hàm trả về một 'std :: tuple' và tôi gọi 'std :: get <0>' trên nó, tôi mong đợi sẽ nhận được một 'int' đơn giản, không phải là' int && '. Bạn có thể cho tôi một ví dụ cụ thể nơi bạn muốn một cái gì đó khác không? –
Không phải là quá tải của 'get' cần thiết cho các ràng buộc có cấu trúc hiệu quả? –