2010-03-11 52 views
11

tôi có mã này:Visual Studio 2010 và std :: chức năng

#include <iostream> 
#include <functional> 

struct A 
{ 
    int operator()(int i) const { 
     std::cout << "F: " << i << std::endl; 
     return i + 1; 
    } 
}; 

int main() 
{ 
    A a; 
    std::tr1::function<int(int)> f = std::tr1::ref(a); 
    std::cout << f(6) << std::endl; 
} 

Mục đích là để vượt qua các đối tượng functor bởi một reference_wrapper, trong một cách để tránh các cuộc gọi bản sao costructor vô dụng. tôi mong đợi đầu ra sau đây:

F: 6 
7 

Nó hoạt động một cách chính xác với GCC> = 4.4.0, Visual Studio 2008 và với đẩy mạnh bằng cách thay namespace std :: tr1 với đẩy mạnh. Nó chỉ không hoạt động với Visual Studio 2010 mới cả Express Beta 2 và Release Candidate.

Tính năng C++ mới này có bị lỗi trong vs2010 không? Hoặc có một số sai lầm hoặc lạm dụng trong mã?

+0

Làm thế nào nó không hoạt động? – UncleBens

+0

@ litb: Tôi nghĩ rằng OP có vấn đề với việc sử dụng lớp 'std :: tr1 :: ref' và * không * tăng trên VS2010. – dirkgently

+0

Đây là việc xây dựng sản phẩm của VS2010: http://pastebin.com/YQf4Qe8W –

Trả lời

11

Tôi nghĩ rằng tôi đã tìm ra lý do. Đây là những gì TR1 3.4/2 nói về result_of<T(A1, A2, ..., AN)>::type, được sử dụng trong việc xác định kiểu trả về của reference_wrapper<T>::operator():

Việc thực hiện có thể xác định các thành viên loại thông qua bất kỳ phương tiện sản xuất các loại chính xác của biểu thức f (t1, t2, ..., tN) cho các loại nhất định. [Chú ý: Mục đích là triển khai được phép sử dụng móc biên dịch đặc biệt lưu ý end]

Và sau đó đoạn 3:

Nếu F không phải là một đối tượng chức năng xác định bởi các tiêu chuẩn thư viện, và nếu triển khai không thể xác định loại biểu thức f (t1, t2, ..., tN) hoặc nếu biểu thức không đúng định dạng thì việc triển khai sẽ sử dụng quy trình sau để xác định loại thành viên:

  • Nếu F là một loại lớp có khả năng cv không có memb er có tên result_type hoặc nếu typename F::result_type không phải là một loại:
    • Nếu N = 0 (không đối số), loại bị vô hiệu.
    • Nếu N> 0, gõ là typename F::template result<F(T1, T2,..., TN)>::type

Các thông báo lỗi là một artefact cố gắng những mùa thu-lưng. Cung cấp một typedef cho result_type đến int và nó sẽ hoạt động, tôi nghĩ vậy. Lưu ý rằng trong C++0x, điều này là khác nhau. Nó không dựa trên mẫu result_type hoặc mẫu result vì nó có thể sử dụng decltype.

Nếu với <functional> không thành công với MSVC10 ở chế độ C++ 0x, nó có mùi giống như một lỗi, tôi sẽ nói. Nhưng có lẽ ai đó biết chuyện gì đang diễn ra. Có thể (nhưng không được đảm bảo) hoạt động với <tr1/functional> ở chế độ C++ 0x nếu tiêu đề đó chọn để thực hiện theo cách decltype thay vì ::result_type. Tôi sẽ typedef result_type - theo cách đó tôi nghĩ rằng nó luôn luôn nên làm việc bất kể cho dù các tiêu đề tr1 được sử dụng hoặc tiêu đề c++0x.


Cũng cần chú ý rằng boost::tr1 nói trong tài liệu hướng dẫn của nó mà nó không hỗ trợ các nhà điều hành chức năng cuộc gọi (nhưng nó chỉ hỗ trợ chuyển đổi ngầm để T&).

+1

Vâng, điều này khắc phục vấn đề: D Nó là một đáng tiếc cho vs2010 cho hồi quy này đối với phiên bản 2008 trước đó ... Bản nháp gần đây nhất yêu cầu trình biên dịch có thể tự động nhận ra kiểu trả về. http://www.open-std.org/JTC1/SC22/ WG21/docs/papers/2009/n3000.pdf Đoạn 20.7.4 –

1

tôi gặp phải một vấn đề tương tự ở đây: Prevent unnecessary copies of C++ functor objects

Để làm cho nó biên dịch trên MSVC10, tôi đã phải lấy được đối tượng chức năng của tôi từ std :: unary_function.

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