Giải pháp tốt nhất là sử dụng STL functional library. Bằng cách phát hiện vị từ của bạn từ unary_function<SomeType, bool>
, khi đó bạn sẽ có thể sử dụng hàm not1
, thực hiện chính xác những gì bạn cần (tức là phủ nhận một biến vị ngữ đơn).
Đây là cách bạn có thể làm điều đó:
struct FindPredicate : public unary_function<SomeType, bool>
{
FindPredicate(const SomeType& t) : _t(t) {}
bool operator()(const SomeType& t) const {
return t == _t;
}
private:
const SomeType& _t;
};
bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind)
{
return find_if(v.begin(),
v.end(),
not1(FindPredicate(valueToFind))) == v.end();
}
Nếu bạn muốn cuộn giải pháp của riêng bạn (đó là, IMHO, không phải là lựa chọn tốt nhất ...), tốt, bạn có thể viết một dự đoán đó là sự phủ định của người đầu tiên:
struct NotFindPredicate
{
NotFindPredicate(const SomeType& t) : _t(t) {
}
bool operator()(SomeType& t) {
return t != _t;
}
private:
const SomeType& _t;
};
bool AllSatisfy(std::vector<SomeType>& v) {
return find_if(v.begin(),
v.end(),
NotFindPredicate(valueToFind)) == v.end();
}
Hoặc bạn có thể làm tốt hơn và viết một negator mẫu functor, như:
template <class Functor>
struct Not
{
Not(Functor & f) : func(f) {}
template <typename ArgType>
bool operator()(ArgType & arg) { return ! func(arg); }
private:
Functor & func;
};
mà bạn có thể sử dụng như sau:
bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind)
{
FindPredicate f(valueToFind);
return find_if(v.begin(), v.end(), Not<FindPredicate>(f)) == v.end();
}
Tất nhiên, giải pháp thứ hai là tốt hơn bởi vì bạn có thể tái sử dụng struct Không với mỗi functor bạn muốn.
Và sau đó bạn có thể thêm chức năng mẫu khuôn mẫu giống như người sgi đã trả lại đối tượng Không mà không cần phải chỉ định loại đó. –
xtofl