Do sau:Tôi có thể viết một hàm C++ chấp nhận cả một con trỏ thô và một con trỏ thông minh?
struct Foo
{
int bar() const;
};
struct IsEqual : public std::unary_function<Foo*, bool>
{
int val;
IsEqual(int v) : val(v) {}
bool operator()(const Foo* elem) const
{
return elem->bar() == val;
}
};
Tôi có một container của Foo*
và tôi sử dụng std::find_if
và std::not1
để tìm hiểu xem có bất kỳ yếu tố trong container nơi bar()
lợi nhuận một cái gì đó khác biệt so với một giá trị nhất định. Mã trông giống như sau:
// Are all elements equal to '2'?
bool isAllEqual(const std::vector<Foo*> &vec)
{
return find_if(vec.begin(), vec.end(), std::not1(IsEqual(2))) == vec.end();
}
Tua nhanh trong tương lai và bây giờ tôi có một vùng chứa khác, lần này có chứa std::tr1::shared_ptr<Foo>
. Tôi rất muốn chỉ đơn giản là tái sử dụng functor của tôi trong một phiên bản quá tải của isAllEqual()
. Nhưng tôi không thể. Foo*
và shared_ptr<Foo>
là các loại khác nhau. Và tôi cần phải kế thừa từ unary_function
để tôi có thể sử dụng not1
. Nó sẽ thanh lịch hơn nếu tôi có thể tránh viết cùng một functor hai lần.
Câu hỏi:
- Có cách nào để viết
IsEqual
để nó có thể sử dụng cả hai con trỏ liệu và thông minh? - Tôi đã tự còng tay mình bằng cách sử dụng
std::not1
? Tôi có nên viếtIsNotEqual
thay thế không?
Hạn chế:
- tôi không thể sử dụng bất cứ điều gì từ thư viện boost.
- Trình biên dịch của chúng tôi không đủ để hỗ trợ C++ 0x lambdas.
Điều này nghe giống như ví dụ về các mẫu sẽ đẹp. – GWW
@Kristo: Trình biên dịch của bạn có đủ mát để cung cấp các công cụ C++ 0x khác, như 'std :: begin'? –
@Ben, chúng tôi đang sử dụng gcc 4.1.2, vì vậy có lẽ không. 'std :: begin' và' std :: end' không đáng kể để viết. –