Thực ra, vấn đề chính với &buffer[0]
(lưu ý sự vắng mặt của các dấu ngoặc đơn) không phải là nó không thực sự đẹp. (Đó là chủ quan anyway. Tôi nhớ tìm thấy buffer.begin(), buffer.end()
không đẹp chút nào, khi lần đầu tiên tôi học cách sử dụng STL.)
Vấn đề chính là nó gọi hành vi không xác định bất cứ khi nào buffer
trống - và hầu hết mã không bao giờ kiểm tra . Đó là lý do tôi đặt chúng thành hộp công cụ của tôi:
template <class T, class TAl>
inline T* begin_ptr(std::vector<T,TAl>& v)
{return v.empty() ? NULL : &v[0];}
template <class T, class TAl>
inline const T* begin_ptr(const std::vector<T,TAl>& v)
{return v.empty() ? NULL : &v[0];}
template <class T, class TAl>
inline T* end_ptr(std::vector<T,TAl>& v)
{return v.empty() ? NULL : (begin_ptr(v) + v.size());}
template <class T, class TAl>
inline const T* end_ptr(const std::vector<T,TAl>& v)
{return v.empty() ? NULL : (begin_ptr(v) + v.size());}
Sử dụng này, bạn có thể viết mã của bạn như
callFunction(begin_ptr(buffer), buffer.size());
Dù begin_ptr(buffer)
là đẹp hơn &buffer[0]
còn lại để bạn có thể quyết định. Tuy nhiên, cho rằng NULL
nên được kiểm tra cho mỗi đối số hàm con trỏ, nó chắc chắn là an toàn hơn.
Bạn nên đổi tên đệm để elegantBuffer ... :) –
Can Bạn không nhận được callFunction để chấp nhận một vector? điều này dường như với tôi là cách thanh lịch thực sự. Nếu không, bạn đang bị mắc kẹt trong vùng đất không có đất trống giữa C và C++. –
@bismuth: Tôi biết nó sẽ là một giải pháp tốt đẹp để thay đổi chức năng của người tiêu dùng để chấp nhận vectơ, nhưng nó không phải là một lựa chọn. Trong thực tế, tôi chỉ sử dụng các vector như là một phân bổ một lần kích thước chưa biết trước. – sharptooth