2015-02-10 13 views
13

Tôi có một chút mã không thành công theo VS2015, nhưng hoạt động theo GCC. Tôi khá chắc chắn lỗi là với Visual Studio nhưng muốn chắc chắn rằng sự hiểu biết của tôi về decltype (tự động) là chính xác.destructor được gọi là trước khi tạm thời nên nằm ngoài phạm vi

#include <iostream> 
using namespace std; 

string zero_params() 
{ 
    return "zero_params called."; 
} 

template< typename F > 
auto test1(F f) -> decltype(auto) 
{ 
    return f(); 
} 

int main() { 
    cout << std::is_rvalue_reference< decltype(test1(zero_params)) >::value << endl; 
    cout << test1(zero_params) << endl; 

    cout << "Done!" << endl; 
    return 0; 
} 

Trong Visual Studio, chuỗi được trả về bởi zero_params được suy luận là tham chiếu rvalue. Hơn nữa, hàm hủy của đối tượng đó được gọi bên trong test1() trong đó trả về từ cuộc gọi đến f xảy ra (có vẻ như một nơi hợp lý để hủy một đối tượng & &).

Theo GCC, chuỗi trả về không được suy luận là tham chiếu giá trị. Hàm hủy được gọi sau khi sử dụng trong câu lệnh cout như tôi mong đợi.

Xác định kiểu trả về là 'chuỗi' thay vì decltype (tự động) dưới Visual Studio sửa chữa nó, cũng như sử dụng remove_reference_t về sự trở lại của f() bên test1.

Kỳ vọng của tôi sẽ là GCC là đúng như chức năng chữ ký cho zero_params() là chuỗi, không phải chuỗi & & vì vậy tôi mong chờ việc không tham chiếu đến 'bong bóng lên' với kiểu trả về của test1 nếu nó sử dụng decltype (Tự động).

Đây có phải là đánh giá chính xác không?


MUỘN EDIT:

Một cách khác tôi đã tìm thấy để làm được việc này với VS2015 là để bọc các chức năng dành cho Test1 trong một lambda:

cout << test1(zero_params) << endl; 

tới:

cout << test1([](auto&&... ps) { return zero_params(std::forward<decltype(ps)>(ps)...); }) << endl; 
+5

Phải, 'f()' là giá trị, vì vậy 'decltype' nên suy ra' std :: string' thay vì 'std :: string &&'. –

+3

Vui lòng gửi báo cáo lỗi trên [MS Connect] (https://connect.microsoft.com/VisualStudio/) và đăng liên kết tại đây. Điều này _really_ cần phải được cố định trước khi VS2015 đi đến RTM nếu 'decltype (tự động)' được dự định là bất cứ điều gì khác hơn là vô ích ... – ildjarn

+0

Thật không may MS Connect nói với tôi rằng tôi không được phép gửi báo cáo lỗi. Tuy nhiên trong Visual Studio tôi đã làm điều tốt nhất tiếp theo - gửi phản hồi bằng cách sử dụng 'khuôn mặt cau mày' của họ bao gồm ảnh chụp màn hình của mã thử nghiệm với mô tả. Thật không may tôi không nghĩ rằng phương pháp này là dễ theo dõi? Hy vọng rằng một người nào đó vượt qua nó đến đúng bộ phận – qeadz

Trả lời

2

Vì vậy, based on the comments chúng tôi có thể kết luận:

Lỗi là:

  • Trình biên dịch nên đã suy luận kiểu trả về là chuỗi
  • Nó thực sự suy luận nó là chuỗi & &
  • Do đó nó bị phá hủy giá trị sớm

Các cách giải quyết là:

  • Không sử dụng decltype (tự động) cho kiểu trả về của hàm
  • Bó chức năng trong một biểu thức lambda trước khi đi qua nó trong
+0

Chúng tôi có thể nhận được những nhận xét được tích hợp vào câu trả lời này không? Bình luận là tạm thời. –

+1

https://connect.microsoft.com/VisualStudio/feedback/details/1124457/decltype-auto-deducing-wrong-type-in-some-cases –

Các vấn đề liên quan