Использование пользовательских унарных предикатов с boost::mpl::find_if в C

#c #boost #boost-mpl

#c #boost #boost-mpl

Вопрос:

У меня есть несколько разных типов классов, каждый с функцией-членом GetParameterString() , которая возвращает строку, специфичную для класса. Я хотел бы иметь возможность хранить эти типы классов в a boost::mpl::list и сравнивать GetParameterString с тестовой строкой, которую я получаю из другого источника. Итак, если у меня есть 3 типа классов, я бы хотел сделать что-то вроде следующего:

 const std::string input_string = "Random String";

using ClassTypes = boost::mpl::list<ClassA, ClassB, ClassC>;
auto it = boost::mpl::find_if<ClassTypes>( [amp;input_string](auto next_class){
          return input_string.compare(next_class.GetParameterString() )
});
it->CallSomeOtherCommonClassMethod();
  

Здесь есть две проблемы. Сначала возвращаемое значение является an int , а не a bool . Но что еще более важно, то, как я настроил вызов boost::mpl::find_if , кажется неправильным, даже если я возвращаю a bool .

Одно из моих требований здесь — придерживаться boost::mpl. Заранее спасибо!

Ответ №1:

Итак, я склоняюсь к мысли, что мое использование boost::mpl::find_if неверно, в отличие от того, чтобы не использовать boost::mpl в качестве библиотеки только для компиляции, используемой для типов. Для справки я использую boost::mpl::for_each in в следующем, без каких-либо проблем и получаю именно то, что хочу:

 boost::mpl::for_each<ClassTypes>([amp;input_string](auto next_class) {
     if (next_class.GetParameterString() == input_string) {
               // DO SOMETHING
     }});
  

Комментарии:

1. Пожалуйста, удалите этот ответ и сделайте его частью вашего вопроса.

Ответ №2:

boost::mpl библиотека в основном работает только во время компиляции и работает исключительно с типами, а не со значениями ( boost::mpl::for_each является исключением). Результатом его find_if является один из классов, а не значение какого-либо типа. Переданный в нем «лямбда» также не является обычным лямбдой C .

Возможно, вы сможете достичь того, чего хотите, если getParameterString() это static constexpr функция-член. Вам нужно будет выяснить, как создать правильный тип Predicate . Как только у вас это будет, ваш код должен выглядеть так:

 using ClassTypes = boost::mpl::list<ClassA, ClassB, ClassC>;
using iter = boost::mpl::find_if<ClassTypes, Predicate>::type;
boost::mpl::deref<iter>::type::CallSomeOtherCommonClassMethod();
  

Комментарии:

1. В моем примере ClassA, ClassB и ClassC являются типами классов. Я смог приступить boost::mpl::for_each к работе над другой проблемой, поэтому я не думаю, что моя путаница связана с работой с типами. Является ли моя ошибка здесь в том, что я смешиваю типы только для компиляции со строками времени выполнения boost::mpl::find_if ? То есть, должен ли мой предикат быть только во время компиляции?