Mục đích của cbegin
/cend
là để giải quyết một vấn đề cụ thể. Hãy xem xét mã này:
std::vector<int> & v = //... v is a non-const reference
// For clarity, I want this iterator to be a const_iterator.
// This works because iterator is implicitly convertible to const_iterator
std::vector<int>::const_iterator iter = find(v.begin(),v.end(),42);
// (1) Now I want to use iter in an algorithm
std::find(iter, v.end(), 38); //Error, can not deduce the template parameter for Iter.
// (2) This works
std::find(iter, const_cast<const std::vector<int> &>(v).end(), 38);
// (3) This is the same as (2).
std::find(iter, v.cend(), 38);
Vấn đề là, do cách mẫu quy định khấu trừ làm việc, trình biên dịch không thể suy ra lập luận mẫu iterator trong báo cáo (1), vì Container::iterator
và Container::const_iterator
là (khả năng) hai hoàn toàn các loại không liên quan (ngay cả khi loại trước đây có thể chuyển đổi ngầm ở dạng sau).
Câu lệnh (2) không chính xác là đường thẳng, đó là lý do tại sao chúng tôi cầncend()
.
Bây giờ, front()
, back()
et similia tất cả trở lại tham chiếu. Một tài liệu tham khảo không const luôn có thể được suy luận như const trong một chức năng templated, đó là:
template<class T> void f(const T & l, const T & r);
int main()
{
int x; vector<int> v;
//This will works even if the return type of front() is int&.
f(x, v.front());
}
Kể từ Container::const_reference
là yêu cầu của tiêu chuẩn để được bằng const Container::value_type &
, cfront()
/cback()
không mua chúng tôi bất cứ điều gì.
Điều đáng nói là thư viện vùng chứa khác (xem bạn Qt) được triển khai bằng cách sử dụng Sao chép-ghi-ghi. Điều này có nghĩa là việc gọi hàm const trên vùng chứa đó có khả năng rẻ hơn nhiều so với việc gọi phiên bản không phải là const tương đương, đơn giản là vì không phải const có thể sao chép toàn bộ vùng chứa dưới mui xe.
Vì lý do này, các thùng chứa Qt có rất nhiều constFunction
trong giao diện của họ và người dùng có quyền tự do chọn đúng.
Chúng bị quá tải, tức là'const_reference front() const;' và 'tham chiếu front();' – jrok
Tôi không thấy cần có hàm 'cfront'. Vấn đề quan trọng sẽ giải quyết là gì? 'cbegin' /' cend' được yêu cầu khá thường xuyên, đó là sự biện minh cho nhóm làm việc để giới thiệu hàm đó. – Columbo
@Columbo: ai đang đếm bao nhiêu lần sử dụng các chức năng không tồn tại trong tổng số các chương trình C++? Tôi biết ủy ban là một vòng tròn của các trình thuật sĩ, nhưng họ có thể đọc được suy nghĩ của tất cả các nhà phát triển C++ là mới đối với tôi. Nghiêm túc, mặc dù, tiêu chuẩn C++ không phải là một cuộc thi phổ biến. Nếu bạn thêm một cơ chế mới, bạn nên thêm nó ở mọi nơi nó hữu ích, không dừng lại nửa chừng, hay bạn nên? –