2016-09-01 13 views
13

Theo như tôi biết, tôi không thể khai báo tham chiếu rvalue thành void.
Như một ví dụ, đoạn mã sau là vô hình thành:Is std :: declval <void>() một biểu thức hợp lệ?

void f(void &&v) { } 

Từ [20.2.6/1] (hàm mẫu declval), chúng tôi có một tuyên bố cho declval đó là:

template <class T> 
add_rvalue_reference_t<T> 
declval() noexcept; 

Như vậy, declval<void> (cho tôi nói) sẽ cho kết quả là trong void &&, mà tôi đoán rằng nó đã bị hỏng hình thành cũng như trong ví dụ trước.

Dù sao, tối thiểu, làm việc Ví dụ sau biên dịch:

#include<utility> 

int main() { 
    decltype(std::declval<void>())* ptr = nullptr; 
} 

Lưu ý rằng sau đây là đúng quá:

static_assert(std::is_same<decltype(std::declval<void>()), void>::value, "!"); 

tôi dự kiến ​​sẽ có nó được void&& như đã đề cập trước đó (hoặc tốt hơn , Tôi đã mong đợi nó không biên dịch được).
Thực ra, nó là một tham chiếu giá trị cho bất kỳ loại không tham chiếu nào khác.
Như một ví dụ:

static_assert(std::is_same<decltype(std::declval<int>()), int&&>::value, "!"); 

declval<void> một biểu thức hợp lệ hay không? Mã trên có hợp pháp không?
Tại sao hành vi trong trường hợp void khác với bất kỳ loại nào khác? (Đối với nó sẽ không làm việc nếu không có thể là một câu trả lời, nếu mã là hợp pháp).

Nếu nó hợp pháp, tiêu chuẩn cho phép điều đó ở đâu? Tôi đã không thể tìm thấy trường hợp.
Tất nhiên, tiêu chuẩn cho biết:

Thông số mẫu T của khai báo có thể là loại không đầy đủ.

Dù sao, ở đây nó sẽ dẫn đến loại không chấp nhận được (void&&) và nó hoạt động xung quanh nó loại bỏ tham chiếu rvalue.

Trả lời

9

add_rvalue_reference<T> chỉ các kết quả trong T&& nếu T là loại có thể tham chiếu được. Vì vậy, khi Tvoid, kết quả chỉ là void. Đây cũng là lý do tại sao bạn có thể add_rvalue_reference<int&&> và không gặp lỗi khi cố gắng tạo tham chiếu đến tham chiếu. (Cùng với tham chiếu lvalue.)

+0

Damnit. Rõ ràng bây giờ bạn đã chỉ ra. Tôi không nghĩ về cách 'add_rvalue_reference' hoạt động, tôi đã thiên vị với' declval'. Cảm ơn bạn. Một câu hỏi khá ngu ngốc, nhưng đây là một câu trả lời hay cho những người sẽ mắc sai lầm tương tự trong tương lai. – skypjack

+2

@skypjack: Thực ra, tôi không biết đây là trường hợp đi vào, câu hỏi của bạn khiến tôi phải nhìn. :) Câu hỏi hay. – GManNickG

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