Подход алгоритмов STL, лямбда, локальные классы и другие подходы - PullRequest
2 голосов
/ 02 ноября 2008

Одна из вещей, которая кажется необходимой при использовании STL, - это способ задания локальных функций. Многие функции, которые я обычно предоставляю, не могут быть созданы с помощью инструментов создания объектов функций STL (например, bind), я должен вручную свернуть свой объект функций.

Поскольку стандарт C ++ запрещает использование локальных типов в качестве аргументов в экземплярах шаблонов, лучшее, что я смог использовать, - это создать небольшую библиотеку (просто показывая соответствующие части)

// library header
class MyFunctionBase<R,T>  
{  
 public:  
   virtual ~MyFunctionBase();  
   virtual R operator()(const T &) const=0;  
};    


class  MyFunction<R,T> 
{   
    MyFunctionBase<R,T> *b; 
 public: 
    ~MyFunction()
    {
       delete b;
    }
    virtual R operator()(const T &) const
    {
        return (*b)(T);
    } 
};


// source file
....

    class func: public MyFunctionBase  ...
    std::stl_alg(....    MyFunction(new funct));

Это всегда казалось мне громоздким. Я думаю, что люди в комитете ISO тоже так считают и добавили лямбду в C ++.

Между тем, как компиляторы решили эту проблему? (Особенно для компиляторов Windows.)

Исправление, которое может немного прояснить. Changelog: 2 ноября заменить, чтобы уточнить Поскольку стандарт C ++ запрещает локальные классы как объекты функций

Ответы [ 3 ]

4 голосов
/ 02 ноября 2008

Стандартный способ - это "функтор" - в основном, struct, который поставляет operator()

Например:

struct MyMinFunctor {
  bool operator()(const int& a, const int& b) { return a > b; }
};

vector<int> v;
sort(v.begin(), v.end(), MyMinFunctor());

Поскольку это структура / класс, вы можете создать подкласс любой из вещей, таких как 'binary_operator', а также поддерживать состояние для более продвинутых функторов.

1 голос
/ 02 ноября 2008

Boost.Bind, Boost.Function и Boost.Lambda - ваши друзья.

1 голос
/ 02 ноября 2008

С C ++ 0x вы можете использовать лямбда-выражения (как вы упомянули):

for_each(container.begin(), container.end(),
  [](auto item) {
    // do something with item
  }
  );

Это уже доступно в MS Visual C ++ 2010 (в настоящее время в Community Tech Preview) и GCC 4.3.x (с флагом компилятора -std = c ++ 0x). Тем не менее, без лямбды, вам просто нужно предоставить тип, который:

  1. По умолчанию конструктивно
  2. Является ли копия конструируемой
  3. Определяет перегрузку оператора функции

Есть некоторые алгоритмы, которые требуют двоичные функциональные объекты, в то время как есть некоторые, которые требуют унарные функциональные объекты. Обратитесь к документации STL вашего поставщика, чтобы узнать, какие именно алгоритмы требуют бинарных функциональных объектов, а какие требуют унарных функциональных объектов.

Одна вещь, на которую вы также можете обратить внимание - это новые реализации bind и function в TR1 (основанные на Boost.Bind и Boost.Function).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...