Sử dụng bí danh mẫu trên mẫu
Đọc cuốn sách Một chuyến tham quan c ++ (xuất bản lần thứ hai), năm 2018 , tôi không hiểu lời giải thích về các mẫu (tôi sẽ giải thích bên dưới).
Hai chữ ký hàm được đưa ra cho một find_all
hàm trả về a vector
trong iterator
s cho tất cả các lần xuất hiện của một giá trị nhất định trong một giá trị nhất định container
.
# 1:
template<typename C, typename V>
vector<typename C::iterator> find_all(C& c, V v);
# 2:
template<typename T>
using Iterator = typename T::iterator;
template<typename C, typename V>
vector<Iterator<C>> find_all(C& c, V v) ;
Cả hai đều có thể được sử dụng như thế này:
string m {"Mary had a little lamb"};
for (auto p : find_all(m,'a')) // here p is a string::iterator
cout << *p << endl; // spoiler alert : this will print 'a's
# 2 sử dụng mẫu bí danh được cho là
ẩn chi tiết triển khai bằng cách giới thiệu một bí danh kiểu cho Iterator
của tác giả.
Mặc dù tôi nghĩ rằng tôi hiểu cả cách sử dụng của các mẫu, tôi không hiểu tại sao # 2 lại "ẩn chi tiết triển khai" và tại sao nó được ưu tiên ... Mọi người có thể giải thích cho tôi không?
Cảm ơn !
postscriptum : Tôi đã không cung cấp cho bài đăng định nghĩa của các chức năng (giống nhau cho cả hai chữ ký) vì tôi nghĩ nó không hữu ích, nhưng tôi sẽ thêm nó nếu ai cần.
Trả lời
Giả sử bạn có một cơ sở mã như
template<typename C, typename V>
vector<typename C::iterator> first(C& c, V v);
template<typename C, typename V>
vector<typename C::iterator> second(C& c, V v);
template<typename C, typename V>
vector<typename C::iterator> third(C& c, V v);
template<typename C, typename V>
vector<typename C::iterator> fourth(C& c, V v);
...
Nếu bạn quyết định muốn thay đổi để trả về một vectơ const_iterator
thay vì iterator
, bạn cần phải thay đổi tất cả các hàm đó. Khi đang sử dụng
template<typename T>
using Iterator = typename T::iterator;
template<typename C, typename V>
vector<Iterator<C>> first(C& c, V v);
template<typename C, typename V>
vector<Iterator<C>> second(C& c, V v);
template<typename C, typename V>
vector<Iterator<C>> third(C& c, V v);
template<typename C, typename V>
vector<Iterator<C>> fourth(C& c, V v);
tất cả những gì bạn phải làm là thay đổi
template<typename T>
using Iterator = typename T::iterator;
đến
template<typename T>
using Iterator = typename T::const_iterator;
và bạn đã hoàn thành. Đây là cách nó "ẩn chi tiết triển khai".