Это зависит от реализации T
.Давайте придерживаться вашего примера класса Car
.Предположим, что класс выглядит примерно так:
class Car {
public:
Car(std::string color, unsigned int number_of_doors,
unsigned int top_speed);
// getters for all these attributes
// implementation of operator< as required for std::set
};
operator<
должен упорядочить экземпляры Car
на основе всех атрибутов , чтобы сделать поиск всех атрибутов возможным.В противном случае вы получите неверные результаты.
Таким образом, вы можете создать экземпляр автомобиля, используя только эти атрибуты.В этом случае вы можете использовать std::set::find
и предоставить временный экземпляр Car
с атрибутами, которые вы ищете:
car_set.find(Car("green", 4, 120));
Если вы хотите найти экземпляр Car
, указав толькоподмножество его атрибутов, как и все зеленые автомобили, вы можете использовать std::find_if
с пользовательским предикатом:
struct find_by_color {
find_by_color(const std::string & color) : color(color) {}
bool operator()(const Car & car) {
return car.color == color;
}
private:
std::string color;
};
// in your code
std::set<Car>::iterator result = std::find_if(cars.begin(), cars.end(),
find_by_color("green"));
if(result != cars.end()) {
// we found something
}
else {
// no match
}
Обратите внимание, что второе решение имеет линейную сложность, поскольку оно не может полагаться на любой порядок,может не существовать для предиката, который вы используете.Первое решение, однако, имеет логарифмическую сложность, так как оно может выиграть от порядка std::set
.
Если, как предлагает @Betas комментарий к вашему вопросу, вы хотите составить предикаты во время выполнения, вы бынужно написать несколько вспомогательных классов для составления разных предикатов.