Sử dụng bí danh mẫu trên mẫu

Jan 09 2021

Đọ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_allhàm trả về a vectortrong iterators 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

6 NathanOliver Jan 09 2021 at 05:54

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_iteratorthay 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".