Обход вложенного функтора (C ++) - PullRequest
3 голосов
/ 25 октября 2009

Есть ли способ передать foo_ за пределы main? Я видел кое-что о Boost в другом вопросе о функторах. Похоже, это может сработать. Вот ответ с упоминанием Boost в этом вопросе. Если я могу, я бы хотел избежать Boost.

#include <iostream>

int main()
{
    class foo {
        public:
        void operator()() {
            std::cout << "Hello" << std::endl;
        }
    };

    foo foo_;
    foo_();
    return 0;
}

Ответы [ 5 ]

4 голосов
/ 25 октября 2009

Нет, в настоящее время локальные типы не могут входить в шаблоны (в противном случае вы могли бы использовать boost или std :: tr1 :: function). Тем не менее, вы могли бы сделать это ООП, где Foo наследует что-то (с виртуальной функцией opeator (), которую реализует ваш foo), и вместо этого вы передаете poo в Foo.

1 голос
/ 25 октября 2009

Возможно использовать адрес статической функции локального класса. Однако operator () должен быть нестатической функцией-членом, поэтому вам нужно дать ей имя:

#include <iostream>

template <class T>
void bar(T f)
{
    f();
}

int main()
{
    class foo {
        public:
        static void do_it() {
            std::cout << "Hello" << std::endl;
        }
    };
    bar(&foo::do_it);
    return 0;
}
1 голос
/ 25 октября 2009

Функциональные локальные классы нельзя использовать в качестве аргументов шаблона, если вы это имеете в виду Это будет поддерживаться только C ++ 0x.

0 голосов
/ 25 октября 2009

Я не думаю, что можно вызвать члена класса, который не определен в текущей области видимости. В этом случае функтор не сохраняет состояния и ведет себя как функция, которая не принимает параметров и не возвращает значений, поэтому вы можете назначить ее экземпляр необработанному указателю на функцию. Однако это уже не foo : это просто указатель на функцию.

Одним из решений является получение foo из чисто виртуального базового класса, определенного в глобальной области видимости, такого как:

class base
{
public:
    void operator()() { doit(); }
protected:
    virtual void doit() = 0;
};

int main()
{
    class foo
    {
    public:
        void operator()() { doit(); }
    protected:
        virtual void doit()
        {
            std::cout << "Hello" << std::endl;
        }
    };
 }

Теперь вы можете передавать экземпляр foo как base , и виртуальный метод doit () будет вызываться, как и ожидалось.

0 голосов
/ 25 октября 2009

РЕДАКТИРОВАТЬ: это не является действительным C ++, хотя некоторые копилеры принимают его без жалоб.

хорошо, если у вас есть что-то, принимающее функторы в качестве параметра шаблона, вы можете передать ему что угодно, ведя себя как функтор, хотя я не совсем уверен, что вы ищете?

template< class tFunctor >
void UseFunctor( const tFunctor& func )
{
  func();
}

int main()
{
  foo foo_;
  UseFunctor( foo_ );
}
...