tôi quyết định cố gắng để viết một thực hiện bản đồ chức năng trong C++ dùng mẫu có sẵn, và đây là những gì tôi đã đưa ra:chức năng C++ thông qua mẫu lạm dụng
template <
class U,
class V,
template <class> class T
>
class T<V> WugMap(
class T<U>::const_iterator first,
class T<U>::const_iterator second,
V (U::*method)() const)
{
class T<V> collection;
while (first != second)
{
collection.insert(collection.end(), ((*(first++)).*method)());
}
return collection;
}
Bây giờ đây là tất cả tiền phạt và dandy, và thậm chí biên dịch. Vấn đề là, tôi không có ý tưởng làm thế nào để thực sự gọi nó.
Cố gắng cách ngây thơ mang lại các lỗi sau:
prog.cpp:42: error: no matching function for call to
‘WugMap(__gnu_cxx::__normal_iterator<Container*, std::vector<Container,
std::allocator<Container> > >, __gnu_cxx::__normal_iterator<Container*,
std::vector<Container, std::allocator<Container> > >, int (Container::*)()const)’
Theo như tôi có thể nói, tất cả các đối số là chính xác. gcc không gợi ý bất kỳ lựa chọn thay thế nào, điều này dẫn tôi đến việc tin rằng định nghĩa của tôi về WugMap là nghi ngờ, nhưng nó biên dịch tốt, vì vậy tôi khá lạc lõng. Bất cứ ai có thể hướng dẫn tôi thông qua silliness này?
Nếu bất cứ ai có thể đề xuất cách tốt hơn để viết một hàm như thế này sẽ hỗ trợ tiêu thụ bất kỳ loại bộ sưu tập nào chứa bất kỳ loại đối tượng nào, tôi sẽ xem xét thay đổi nó.
Tôi hiện đang sử dụng Ideone, đó là sử dụng C++ 03, gcc 4.3.4.
Phụ lục 1
Đây có phải là có thể trong C++ 11? Nó đã được gợi ý rằng nó được. Tôi biết các mẫu trong C++ 11 hỗ trợ số lượng các đối số khác nhau vì vậy tôi sẽ sửa đổi các yêu cầu của tôi để phù hợp với điều đó là tốt. Tôi sẽ đặt một chút công sức vào viết cái gì đó lên, nhưng trong khi chờ đợi, đây là những yêu cầu mà tôi đang tìm:
nên có một cái gì đó chữ ký như sau:
C2<V, ...> map(const C1<U, ...>&, V (U::*)(...), ...)
Đó là lấy một số bộ sưu tập C1, chứa các phần tử kiểu U, được xây dựng với một số tham số mặc định, tham chiếu, và cũng lấy một số hàm thành viên (trả về V và lấy một số đối số của các kiểu không xác định) của U và sau đó lấy , theo thứ tự, các đối số được chuyển đến hàm thành viên. Hàm cuối cùng sẽ trả về một tập hợp kiểu C2 chứa các phần tử kiểu V và được khởi tạo với một số lượng các tham số mặc định không xác định.
nên được thể kết nối:
vector<int> herp = map( map( set<Class1, myComparator>(), &Class1::getClass2, 2, 3), &Class2::getFoo);
thưởng điểm nếu tôi không cần phải có lập luận mẫu hay bất kỳ cách rườm rà phụ khác khi sử dụng nó.
std::transform
thật tuyệt vời, nhưng không thể chuỗi.
Có cần phải là vùng chứa không? ['std :: transform'] (http://www.cplusplus.com/reference/algorithm/transform/) trong' 'đã thực hiện điều này với các trình vòng lặp. –
@JonPurdy: Hãy giả vờ rằng std :: transform không tồn tại. Ngoài ra, một tính năng mà việc triển khai này nhằm cung cấp std :: transform không phải là hàm con trỏ thành thành viên (tôi không nghĩ std :: transform có thể hoạt động theo cách này mà không có đối tượng bao bọc). Ngoài ra, std :: transform biến đổi một bộ sưu tập, nó được thiết kế để tạo ra một bộ sưu tập mới của một kiểu có thể khác. – Wug
@DyP: bạn biết đấy, điều đó có thể liên quan đến nó, mặc dù chính xác là gì, tôi không thể hiểu được. Có một số loại quy tắc tinh tế về việc liệu có nên sử dụng 'class' hoặc' typename' không đi vào hoạt động trừ khi template-templates có liên quan hay không. Điều đó có thể giải thích lý do tại sao biên dịch của nó nhưng không được coi là một hàm mặc dù. – Wug