2016-04-01 18 views
5

Mã sau đây biên dịch nhưng sản lượng không xác định đầu ra trong VC++ 2015 (bản phát hành) và lỗi thời gian chạy với other compilers.Gán std :: function <int(int)> thành std :: function <const int & (const int & x)>

#include <functional> 
#include <iostream> 
int main() 
{ 
    std::function<int(int)> f = [](int x) { return x; }; 
    std::function<const int&(const int& x)> g = f; 
    std::cout << g(42) << std::endl; 
} 

Tại sao bài tập g = f; được cho phép?

+0

biên dịch và thực hiện hoàn hảo với tiếng kêu của táo –

+1

Khả năng liên quan cao/có thể có: http://stackoverflow.com/q/32871606/2069064 – Barry

Trả lời

5

Xem xét các mã tương đương viết lại để tránh lambdas hoặc std::function:

int f(int x) { return x; } 
int const& g(int const& x) { return f(x); } 

này được hoàn hảo đang tốt được hình thành, đó vẫn trả về một tham chiếu lủng lẳng để tạm thời và do đó sẽ kết thúc gây ra hành vi không xác định. Mã gốc được trả tiền cho cùng một lý do: bạn hoàn toàn có thể chuyển đổi một đối tượng thành tham chiếu cùng loại. Thật không may, trong trường hợp này.

+0

Cảm ơn bạn. Ví dụ của bạn ít nhất [tạo ra một cảnh báo] (http://codepad.org/o6ejBjn6). Ví dụ với 'std :: function' thì không. –

4

Giá trị có thể bị ràng buộc thành const&. A const& có thể được chuyển đổi thành giá trị.

Kiểm tra này:

int f(int x){return x;} 
int const& g(int const& x){ return f(x); } 

Tương tự như vậy, các cuộc gọi đến g là hợp pháp, không có lỗi, nhưng đọc kết quả của g(42) là UB - tài liệu tham khảo dangles.

Trình biên dịch tốt sẽ thấy tham chiếu bị ràng buộc tạm thời bị trả lại và cảnh báo.

function chỉ cần kiểm tra xem các loại có thể được chuyển đổi giữa; nó không phân tích suốt đời. Có lẽ nó nên, như chúng ta có thể phát hiện lỗi này tĩnh.

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