Chương trình này có được xuất ra 0 hoặc 1 không? Trong bài đọc và hiểu biết về các đoạn trích dẫn từ các tiêu chuẩn C++ 14 của tôi, nó nên in 1, nhưng cả hai GCC và kêu vang in 0 (vì kiểu suy luận là A const
thay vì A const&
):Toán tử điều kiện có cùng loại lớp cơ bản
#include <iostream>
struct A {};
int main()
{
A a;
A const& ra = std::move(a); // #1
std::cout << std::is_same<decltype(true ? ra : std::move(a)),
A const&>::value; // Prints 0
}
trong này trường hợp, ra
là một giá trị A const
và std::move(a)
là giá trị A
xvalue, cả hai loại lớp. Theo tiêu chuẩn về các nhà điều hành có điều kiện (tôi nhấn mạnh), kết quả phải là một lvalue
loại A const
, và do đó các kết quả decltype
phải A const&
:
[expr.cond]/3 Ngược lại, nếu toán hạng thứ hai và thứ ba có các loại khác nhau và hoặc có (có thể là đủ điều kiện cv) lớp loại hoặc nếu cả hai đều là giá trị của cùng một danh mục giá trị và cùng loại ngoại trừ cv-qualification, thì thực hiện để chuyển đổi mỗi toán hạng đó cho loại khác. Quá trình xác định dù một biểu thức toán hạng E1 loại T1 có thể được chuyển đổi để phù hợp với một biểu thức toán hạng E2 loại T2 được định nghĩa như sau:
- Nếu E2 là một giá trị trái: E1 có thể được chuyển đổi để phù hợp với E2 nếu E1 có thể được chuyển đổi hoàn toàn (khoản 4) thành loại "tham chiếu lvalue đến T2", tùy thuộc vào ràng buộc trong chuyển đổi, tham chiếu phải liên kết trực tiếp (8.5.3) với giá trị.
[...]
Trong trường hợp này, E2 là ra
, đó là một giá trị trái, và người kia có thể được chuyển đổi sang implicitely "tài liệu tham khảo giá trị trái để T2", như thể hiện trong dòng // #1
. "tài liệu tham khảo giá trị trái để T2" được dịch là A const&
, vì vậy, std::move(a)
liên kết trực tiếp đến một vế trái của loại A const
, và sau khi chuyển đổi, cả hai toán hạng có cùng loại và loại giá trị, và do đó:
[ expr.cond]/3 Nếu toán hạng thứ hai và thứ ba là các giá trị của cùng một danh mục giá trị và có cùng loại, kết quả là loại danh mục và giá trị đó [...].
Vì vậy, kết quả điều hành phải là một giá trị trái và decltype
kết quả phải là một tài liệu tham khảo, và do đó chương trình sẽ in 1.
điều này có thể ảnh hưởng đến hành vi của 'std :: common_type', không? hoặc ít nhất, việc triển khai mặc định: http://en.cppreference.com/w/cpp/types/common_type –
@ChrisBeck Trong trường hợp cụ thể này không vì các tham số mẫu đầu tiên bị phân rã. –
@ Peregring-lk Bạn nên ** không bao giờ ** sửa đổi một câu hỏi theo cách có thể làm mất hiệu lực nhận xét của người khác (hoặc câu trả lời). – Phil1970