2015-01-08 22 views
5

Tôi muốn quá tải hai chức năng dựa vào việc tranh luận là một đối tượng tạm thời, vì vậy tôi viết mã như thế này:quá tải giữa tham khảo rvalue và tham khảo giá trị trái const trong mẫu

#include <iostream> 

void f(int &&) 
{ 
    std::cout << "&&" << std::endl; 
} 

void f(const int&) 
{ 
    std::cout << "const &" << std::endl; 
} 

int main() 
{ 
    int i; 
    f(i); 
    f(i + 1); 
} 

Và nó corrently đầu ra:

const & 
&& 

Tuy nhiên, khi tôi thay đổi mã để sử dụng mẫu như thế này:

#include <iostream> 

template <typename T> 
void f(T &&) 
{ 
    std::cout << "&&" << std::endl; 
} 

template <typename T> 
void f(const T&) 
{ 
    std::cout << "const &" << std::endl; 
} 

int main() 
{ 
    int i; 
    f(i); 
    f(i + 1); 
} 

Đầu ra sẽ trở thành:

&& 
&& 

Có vấn đề gì? Làm thế nào tôi có thể tối ưu hóa cho đối tượng tạm thời di chuyển khi sử dụng mẫu?

chỉnh sửa:

Thực ra, đây là mã kiểm tra khi tôi đọc C++ Primer. Nó nói:

template <typename T> void f(T&&);  // binds to nonconst rvalues 
template <typename T> void f(const T&); // lvalues and const rvalues 

Sau khi thử nghiệm của tôi, có vẻ như cuốn sách đã phạm sai lầm ở đây.

+0

những gì bạn có nghĩa là bởi * "Làm thế nào tôi có thể tối ưu hóa cho đối tượng tạm thời di chuyển khi sử dụng bản mẫu"* ? 'T &&' chính nó là tối ưu vì nó liên kết với mọi thứ và cho phép bạn khôi phục danh mục giá trị của biểu thức được sử dụng làm đối số –

+0

@PiotrS. Ví dụ, nếu nó liên kết biến i với const T &, và liên kết biểu thức i + 1 với T &&, thì tôi có thể di chuyển tài nguyên từ oject tạm thời được tạo ra bởi i + 1. – delphifirst

+2

đó là lý do tại sao có một chuyển động có điều kiện, đó là 'std: : forward ', tùy thuộc vào loại suy luận cho' T' nó sẽ di chuyển hay không. Bạn không phải sử dụng rõ ràng 'std :: move' cho các giá trị. Lưu ý rằng 'T &&' trong đó 'T' là tham số mẫu kiểu là * tham chiếu chuyển tiếp *, hoạt động khác với tham chiếu rvalue thông thường –

Trả lời

0
template <typename T> 
void f(T &&) 
{ 
    std::cout << "&&" << std::endl; 
} 

Sử dụng phổ chuyển tiếp tài liệu tham khảo và cho phép bất kỳ loại tài liệu tham khảo với sụp đổ.

Bạn phải sử dụng T với một không bối cảnh suy luận như gói mã của bạn vào một cấu trúc:

template <typename T> 
struct helper 
{ 

    void f(T &&) 
    { 
     std::cout << "&&" << std::endl; 
    } 

    void f(const T&) 
    { 
     std::cout << "const &" << std::endl; 
    } 

}; 

template <typename T> 
void f(T &&t) 
{ 
    helper<typename std::decay<T>::type>().f(std::forward<T>(t)); 
} 

Live example

+0

std :: phân rã, std :: forward, ... Có vẻ như tôi phải tìm hiểu thêm trước khi tôi hiểu hành vi này. -_- || – delphifirst

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