boost :: заводское создание boost ::enable_shared_from_this class

#c #boost-asio #shared-ptr #boost-function

#c #boost-asio #общий доступ-ptr #boost-функция

Вопрос:

У меня есть несколько классов, производных от

 class A : public boost::enable_shared_from_this<A> {
    public:
        typedef boost::shared_ptr<A>    pointer;

        static pointer create(tcp::socketamp; socket) {
            return pointer(new A(socket));
        }
    private:
        A(amp;tcp::socket socket) : m_socket(socket) {}

        tcp::socketamp;    m_socket;
}

Class Aa : public A {
    public:
        typedef boost::shared_ptr<Aa>   pointer;

        static pointer create(tcp::socketamp; socket) {
            return pointer(new Aa(socket));
        }

    private:
        Aa(amp;tcp::socket socket) : A(socket) {}
}

Class Ab : public A {
    public:
        typedef boost::shared_ptr<Ab>   pointer;

        static pointer create(tcp::socketamp; socket) {
            return pointer(new Ab(socket));
        }

    private:
        Ab(amp;tcp::socket socket) : A(socket) {}
}
  

[…]

 Class Ax : public A {
    public:
        typedef boost::shared_ptr<Ax>   pointer;

        static pointer create(tcp::socketamp; socket) {
            return pointer(new Ax(socket));
        }

    private:
        Ax(amp;tcp::socket socket) : A(socket) {}
}
  

Я хотел бы создать шаблон factory, используя boost::factory
Я написал что-то вроде этого :

 class MyFactory {
    public:
        static MyFactory* getInstance();

        typedef boost::function< A(tcp::socket) > a_fact;

    private:
        MyFactory() {
            map["Aa"] = boost::bind(boost::factory< Aa::create >, _1);
            map["Ab"] = boost::bind(boost::factory< Ab::create >, _1);
            […]
            map["Ax"] = boost::bind(boost::factory< Ax::create >, _1);
        }

        std::map<std::string, a_fact>   map;
    };
  

И, конечно, это не компилируется…
выдает ошибку :

 MyFactory.cc:13: error: type/value mismatch at argument 1 in template parameter list fortemplate<class Pointer, class Allocator, boost::factory_alloc_propagation AP> class boost::factory’
MyFactory.cc:13: error:   expected a type, got ‘Aa::create’
  

Есть идеи, как мне это реализовать?

Ответ №1:

В документации аргумент, передаваемый factory -template, является типом указателя, который вы ожидаете в результате. Итак, в вашем случае boost::factory<Aa::pointer> .

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

1. Это не сработает, поскольку я должен вызвать статический метод create вместо конструктора…

Ответ №2:

Если кто-нибудь повторит ту же ошибку, вот ответ. Ему не нужно boost::factory работать, достаточно использовать boost::function напрямую.

итак

 class MyFactory {
    public:
        static MyFactory* getInstance();

        typedef boost::function< A(tcp::socket) > a_fact;

    private:
        MyFactory() {
            map["Aa"] = boost::bind(amp;Aa::create, _1);
            map["Ab"] = boost::bind(amp;Ab::create, _1);
            […]
            map["Ax"] = boost::bind(amp;Ax::create, _1);
        }

        std::map<std::string, a_fact>   map;
    };
  

Отлично работает!!!