2015-11-30 14 views
8

Nó đã đi đến sự chú ý của tôi rằng std::forward là vô ích trong bối cảnh này:Tại sao std :: phía trước vô dụng trong bối cảnh này

void consumeObject(std::unique_ptr<Object>&& robj) { 
    myvector.emplace_back(std::forward<std::unique_ptr<Object>>(robj)); 
} 

Tại sao vậy? Tôi nghĩ rằng khi tham chiếu rvalue liên kết với tham số hàm (nghĩa là tôi có thể tham chiếu nó theo tên) nó sẽ trở thành một giá trị trong phạm vi đó và để được chuyển tiếp cần phải được đúc thành tham chiếu rvalue (như trong chuyển tiếp hoàn hảo)).

Tại sao nó sai/vô ích?

+8

"Cast tham chiếu rvalue "không phải là" chuyển tiếp hoàn hảo ". Đó là * di chuyển *. –

+0

Chuyển tiếp hoàn hảo là sự kết hợp của quy tắc khấu trừ đối số mẫu đặc biệt và thu gọn tham chiếu. – Simple

+2

Ngoài ra: chuyển tiếp hoàn hảo liên quan đến "tham chiếu phổ quát" và bạn không có tham chiếu chung; bạn có một tham chiếu rvalue. 'std :: move' là đủ ở đây. – Simple

Trả lời

13

Nó không phải sai sử dụng std::forward đây (per se), nhưng nó là không phù hợp và do đó gây hiểu lầm (trong ý nghĩa đó, bạn có thể nói rằng nó là thực sự sai).

Cách bạn đánh vần "truyền nội dung nào đó đến tham chiếu rvalue cho loại của nó" là std::move. Đó là số chỉ điều mà std::move thực hiện — đó là số static_cast<T&&> nơi bạn không phải đánh vần ra số T.

std::forward là một con thú khác, được thiết kế để sử dụng với chuyển tiếp hoàn hảo. Chuyển tiếp hoàn hảo chỉ xảy ra trong các mẫu, trong đó tham chiếu chuyển tiếp là có thể. Tham chiếu chuyển tiếp là tham chiếu, nhờ quy tắc đặc biệt trong ngôn ngữ, có thể suy ra tham chiếu giá trị hoặc tham chiếu rvalue. Ở đó, bạn cần std::forward<T> để tái kích hoạt danh mục giá trị thích hợp (giá trị hoặc giá trị).

Toy dụ:

void print(int &) 
{ 
    std::cout << "Lvalue\n"; 
} 

void print(int &&) 
{ 
    std::cout << "Rvalue\n"; 
} 

template <class T> 
void perfectForwarder(T &&v) 
{ 
    print(std::forward<T>(v)); 
} 

int main() 
{ 
    int i; 
    perfectForwarder(i); 
    perfectForwarder(std::move(i)); 
    perfectForwarder(42); 
} 

Kết quả sẽ là:

vế trái
rvalue
rvalue

[Live]

+3

Tôi sẽ nói rằng 'std :: forward' chắc chắn là sai ở đây, trong cùng một cách mà mã không thể đọc là sai bất kể nó hoạt động hay không. – bames53

+0

Cảm ơn! Bây giờ tôi đã nhận nó! – Dean

+3

Tôi không nói là * "không cần thiết" *. Nó là khá * gây hiểu nhầm * (cho người đọc). – Nawaz

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