2013-08-13 97 views
12

Giả sử có hai chức năng:Làm cách nào để tạo một bộ tham chiếu const?

void ff(const std::tuple<const int&>) { } 

template < typename TT > 
void gg(const std::tuple<const TT&>) { } 

và các cuộc gọi đến các chức năng:

int xx = 0; 
ff(std::tie(xx)); // passes 
gg(std::tie(xx)); // FAILS !! 

GCC 4.7.2 thất bại trong việc biên dịch dòng cuối cùng và báo cáo một lỗi lưu ý như:

note: template argument deduction/substitution failed: 
note: types ‘const TT’ and ‘int’ have incompatible cv-qualifiers 
note: ‘std::tuple<int&>’ is not derived from ‘std::tuple<const TT&>’ 

Câu hỏi đầu tiên là nếu điều này phù hợp với tiêu chuẩn C++ 11, và nếu không, thì tại sao?

Ngoài ra, để khắc phục sự cố này, người dùng cần chuyển một bộ tham chiếu const đến gg thay vì chuyển một bộ tham chiếu không const (mà std::tie tạo). Điều này có thể được thực hiện bằng cách:

gg(std::tie(std::cref(x))); 

Tuy nhiên, một cuộc gọi thêm để std::cref là loại tẻ nhạt, vì vậy nó sẽ là tuyệt vời để có một cái gì đó giống như ctie mà sẽ làm cho một tuple tài liệu tham khảo const.

Câu hỏi thứ hai là nếu có nhu cầu viết ctie theo cách thủ công và nếu có, thì đây có phải là cách tốt nhất để làm điều đó không?

template < typename... T > 
std::tuple<const T&...> ctie(const T&... args) 
{ 
    return std::tie(args...); 
} 
+3

[. Liên quan, nhưng không phải là một dupe] (http://stackoverflow.com/a/7867662/500104) – Xeo

+2

'trở lại std :: di chuyển (); 'là một mô hình chống - đó là phổ biến tốt hơn để đơn giản 'return ;' Trong trường hợp cụ thể này, 'std :: tie (args ...)' vẫn là một giá trị. [Xem câu trả lời này để thảo luận] (http://stackoverflow.com/a/15981233/923854). – Casey

Trả lời

2

Câu hỏi thứ nhất là nếu điều này phù hợp với các tiêu chuẩn C++ 11, và nếu không, thì tại sao?

Đây là hành vi mong đợi. Trong trường hợp khấu trừ đối số mẫu thứ hai không thành công vì không có T để tuple<const T&> trở thành tuple<int&>.

Trong trường hợp đầu tiên hoạt động vì tuple<int&> được chuyển đổi hoàn toàn thành tuple<const int&>. Đây là một chuyển đổi do người dùng xác định và do đó không được xem xét trong quá trình khấu trừ đối số mẫu.

Câu hỏi của bạn có mùi giống như vấn đề X/Y. Cân nhắc việc đăng câu hỏi thực sự khiến bạn tìm kiếm giải pháp liên quan đến loại kết hợp mẫu/tuple này.

Mẫu chức năng ctie của bạn có vẻ ổn. Nhưng hãy nhớ rằng những thứ như

về cơ bản sẽ tạo ra tham chiếu không đáng kể. Vì vậy, bạn có thể muốn hạn chế ctie chỉ là giá trị.