Я пытаюсь написать общую фабрику obj, используя вариативный шаблон для вызова конструкторов различных классов. код, как показано ниже:
#include <iostream>
#include <string>
#include <memory>
#include <functional>
#include <unordered_map>
template<typename T>
class ObjFactory {
public:
typedef std::shared_ptr<T> ObjPtr;
typedef std::function<ObjPtr(void)> CreatorFunc;
public:
void registerCreator(const std::string &name, const CreatorFunc &creator)
{ m_dictCreator[name] = creator; }
ObjPtr getObj(const std::string &name) const
{
auto it = m_dictCreator.find(name);
return (it == m_dictCreator.end() ? nullptr : (it->second)());
}
private:
std::unordered_map<std::string, CreatorFunc> m_dictCreator;
};
using namespace std;
struct Base {
virtual ~Base() {}
virtual void greet() const
{ cout << "I am Base" << endl; }
};
struct Derived : Base {
Derived() : x(0), y(0) {}
Derived(int a, int b) : x(a), y(b) {}
int x, y;
virtual void greet() const
{ cout << "I am Derived x = " << x << " y = " << y << endl; }
};
template<typename T, typename... Args>
std::shared_ptr<T> create_obj(Args... args) // This OK
// std::shared_ptr<T> create_obj(Args&&... args) // WRONG
{ return std::make_shared<T>(std::forward<Args>(args)...); }
int main()
{
ObjFactory<Base> factory;
factory.registerCreator("default", create_obj<Derived>);
factory.registerCreator("withArgs", std::bind(create_obj<Derived, int, int>, 1, 2));
do {
auto pObj = factory.getObj("default1");
if (pObj) { pObj->greet(); }
} while (0);
do {
auto pObj = factory.getObj("withArgs");
if (pObj) { pObj->greet(); }
} while (0);
return 0;
}
В большинстве примеров аргументы с переменным числом аргументов всегда записываются как «Args && ...» в списке аргументов функций. но это не работает с привязкой, скомпилируйте сообщение об ошибке, подобное этому (clang-902.0.39.2)
ошибка: нет приемлемого преобразования из '__bind (&) (int &&, int &&), int, int>' в 'const ObjFactory :: CreatorFunc' (aka 'const function ()>') factory.registerCreator ("withArgs", std :: bind (create_obj, 1, 2));
После удаления "&&" все работает нормально
Но я не знаю почему?
std::bind
на лямбда (как обычно рекомендуется) работает должным образом.[](){ return create_obj<Derived>(1,2); }
- person super   schedule 10.08.2018std::bind
проводите сеанс, если у вас нет C ++ 11, иначе вам следует использовать лямбда. - person Marek R   schedule 10.08.2018