Các thuật toán tối thiểu thường được trình bày như thế này:min và chuyển tiếp hoàn hảo
template <typename T>
const T& min(const T& x, const T& y)
{
return y < x ? y : x;
}
Tuy nhiên, điều này không cho phép các cấu trúc của mẫu min(a, b) = 0
. Bạn có thể đạt được điều đó với một tình trạng quá tải thêm:
template <typename T>
T& min(T& x, T& y)
{
return y < x ? y : x;
}
Những gì tôi muốn làm là thống nhất hai quá tải này qua chuyển tiếp hoàn hảo:
template <typename T>
T&& min(T&& x, T&& y)
{
return y < x ? std::forward<T>(y) : std::forward<T>(x);
}
Tuy nhiên, g ++ 4.5.0 spits ra một cảnh báo cho min(2, 4)
mà tôi trả lại một tham chiếu đến tạm thời. Tôi đã làm gì sai sao?
OK, tôi hiểu rồi. Vấn đề là với toán tử điều kiện. Trong giải pháp đầu tiên của tôi, nếu tôi gọi min(2, 4)
toán tử điều kiện sẽ thấy một xvalue và do đó di chuyển từ chuyển tiếp x
để tạo ra một đối tượng tạm thời. Tất nhiên nó sẽ là nguy hiểm để trở lại đó bằng cách tham khảo! Nếu tôi chuyển toàn bộ biểu hiện thay vì x
và y
riêng rẽ, trình biên dịch không phàn nàn nữa:
template <typename T>
T&& min(T&& x, T&& y)
{
return std::forward<T>(y < x ? y : x);
}
Được rồi, tôi đã thoát khỏi những tài liệu tham khảo cho các loại số học :)
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type
min(T x, T y)
{
return y < x ? y : x;
}
template <typename T>
typename std::enable_if<!std::is_arithmetic<T>::value, T&&>::type
min(T&& x, T&& y)
{
return std::forward<T>(y < x ? y : x);
}
Hmm có vẻ với tôi rằng ví dụ cuối cùng cũng tạo tạm thời theo FCD. Nhưng điều này có vẻ kỳ lạ: Có vẻ như tạo ra các thời gian để ràng buộc một 'int &&' thành một 'int' xvalue ?! Tôi nghĩ rằng xvalues là refs rvalue ẩn danh mà có thể bị ràng buộc bởi tham chiếu rvalue mà không có thời gian tạo ra? Điều tương tự cũng xảy ra với mã đã sửa đổi của bạn, phải không? Kiểu trả về là 'int &&', và biểu thức trả về là một 'x'ue' int'. Tại sao trình biên dịch không cảnh báo nữa? –
Nếu tôi đọc chính xác 8.5.3', nó nói rằng điều này tạo ra một int tạm thời khi ràng buộc tham chiếu đến xvalue: 'int x = 0; int && rx = (int &&)x; 'Tương tự như vậy khi sử dụng' std :: move'. Điều đó không thể là ý định, tôi nghĩ. –
@Johannes: Bạn đang nói về phần nào trong 8.5.3? – fredoverflow