2011-08-10 42 views
15

Gần đây tôi đã tập trung suy nghĩ về các khái niệm về giá trị, giá trị xvalue và giá trị của C++ 0x, cũng như các tham chiếu rvalue. Tuy nhiên, có một điều vẫn eludes tôi:Tham chiếu rvalue cho loại chức năng là gì?

Điều gì là "tham chiếu rvalue cho loại chức năng"? Nó được đề cập theo nghĩa đen nhiều lần trong bản nháp. Tại sao một khái niệm như vậy lại được giới thiệu? Sử dụng cho nó là gì?

+0

cuối cùng bạn đã hiểu câu trả lời chưa? Tôi đã để lại một bình luận dưới câu trả lời vì vậy nếu bạn nhận thức được sự làm rõ, xin vui lòng cung cấp nó. Cảm ơn –

Trả lời

15

tôi ghét có dạng tròn, mà là một tài liệu tham khảo rvalue hoạt động t ype là một tham chiếu rvalue cho kiểu hàm. Có một thứ như một loại hàm, ví dụ: void(). Và bạn có thể tạo thành một tham chiếu rvalue cho nó.

Về hệ thống phân loại được giới thiệu bởi N3055, đây là một xvalue.

Sử dụng của nó hiếm và tối nghĩa, nhưng nó không phải là vô ích. Hãy xem xét ví dụ:

void f() {} 
... 
auto x = std::ref(f); 

x có kiểu:

std::reference_wrapper<void()> 

Và nếu bạn nhìn vào tóm tắt cho reference_wrapper nó bao gồm:

reference_wrapper(T&) noexcept; 
reference_wrapper(T&&) = delete; // do not bind to temporary objects 

Trong ví dụ này T là chức năng loại void() . Và do đó, khai báo thứ hai tạo thành một tham chiếu rvalue cho kiểu hàm cho mục đích đảm bảo rằng reference_wrapper không thể được xây dựng với một đối số rvalue. Thậm chí nếu T là const.

Nếu không hợp pháp để tạo thành tham chiếu rvalue cho chức năng thì bảo vệ này sẽ dẫn đến lỗi biên dịch ngay cả khi chúng tôi không chuyển giá trị T cho hàm tạo.

+3

Tôi nghĩ bạn có nghĩa là 'void()'. 'void()()' là một sai lầm đáng kinh ngạc của GCC/binutils nhưng [đã được sửa chữa một thời gian trước] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46332). –

+1

@Johannes: Cảm ơn! Đó là * hầu hết * hữu ích! –

+0

Điều này thật đáng sợ và tôi có vấn đề về sự hiểu biết. Về câu cuối cùng về lỗi thời gian biên dịch sẽ không SFINAE chỉ gây ra tuyên bố thứ hai được bỏ qua trong trường hợp này? – Kos

0

Trong tiêu chuẩn C++ cũ sau bị cấm:

int foo(); 
void bar(int& value); 

int main() 
{ 
    bar(foo()); 
} 

vì kiểu trả về của foo() là một rvalue và được thông qua bởi tham chiếu đến bar().

này được phép mặc dù có phần mở rộng của Microsoft cho phép trong visual C++ từ (tôi nghĩ) 2005.

có thể giải quyết mà không C++ 0x (hoặc msvc) sẽ được tuyên bố

void bar(const int& value); 

hoặc sử dụng một temp-biến, tàng trữ sự trở lại giá trị của foo() và đi qua các biến (như tài liệu tham khảo) để thanh():

int main() 
{ 
    int temp = foo(); 
    bar(temp); 
} 
+5

Có lẽ tôi hiểu lầm câu hỏi, nhưng tôi nghĩ rằng OP đang nói về rvalues ​​tham chiếu đến các loại chức năng (ví dụ. lambdas và vv). – user786653

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