I am trying to use boost, C++ with templates, and factory pattern but can't seem to figure out the right syntax for it?

Although this is a C++ question, I am trying to use this with unreal engine ot create my own classes.
Here is the specifics:

  1. Consider a simple constructor in a class with two input arguments,
    concreteclass(_1, _2).
  2. I have a map for this instantiation, map ``.
  3. Also, these classes work with different datatypes concreteclass(_1,_2) is different from concreteclass(_1,_2).

Now that my problem is described above here is what I try to do using boost::factory pattern, classes defined in a string map and datatypes defined in an enum.

First, there is a simple way to demonstrate how boost factory pattern can be used with constructor arguments, the following code nicely works:

// Factory which takes two arguments
struct base {
	base(int alpha) : alpha(alpha) {}
	virtual ~base() = default;
	virtual void print() const = 0;

	int alpha;
};

struct derived : public base {
	derived(int alpha, int beta) : base(alpha), beta(beta) {}
	void print() const override {
		std::cout << alpha << " " << beta << std::endl;
	}

	int beta;
};


void TestBoostFactoryWithTwoArgs()
{
	// Constructor factory with two input args
	{
		std::map<std::string, boost::function<base* (int&, int&)>> factories;
		factories["derived"] = boost::bind(boost::factory<derived*>(), _1, _2);
		int x = 42;
		int y = 51;
		std::unique_ptr<base> b{ factories.at("derived")(x,y) };
		b->print();
	}
	// Factory with two initialized inputs args - binding of values not at run time 
	{
		std::map<std::string, boost::function<base* ()>> factories;
		factories["derived"] = boost::bind(boost::factory<derived*>(), 42, 51);
		std::unique_ptr<base> b{ factories.at("derived")() };
		b->print();
	}
}

Now consider my code - SimpleClasses.h:

// Dummy base class - non template
class IBaseClass
{
public:

};

// Templatized Derived Base class
template <typename T>
class ConcreteClass : public IBaseClass
{
private:
	std::shared_ptr<IBaseClass> m_leftArgument;
	std::shared_ptr<IBaseClass> m_leftArgument;
public:
	ConcreteClass(std::unique_ptr<IBaseClass>& leftArgument, std::unique_ptr<IBaseClass>& rightArgument)
	{
		m_leftArgument = leftArgument;
		m_rightArgument = rightArgument;
	};

	virtual T DoSomething()
	{
		cout << "I did something in Concrete Base Class" << endl;
		return T();
	}; // This is the main reason for creating T

};

template <typename T>
class ConcreteClassA : ConcreteClass
{

};

template <typename T>
class ConcreteClassB : ConcreteClass
{

};

template <typename T>
class ConcreteClassC : ConcreteClass
{

};

Another File, ClassFactory.h :

#pragma once

#include "SimpleClasses.h"
#include <memory> 
#include <map>
#include <boost/functional/overloaded_function.hpp>
#include <boost/functional/factory.hpp>

using namespace std;

// Add More class Keys here
namespace MyClassesNamespace { // These are all string keys
	static const string CLASS_A = "specialclassA";
	static const string CLASS_B = "specialclassB";
	static const string CLASS_C = "specialclassC";
};

enum EMyDataTypes
{
	INT8,
	FLOAT8,
	FLOAT16,
};


// This type def we keep for non templatized base class constructor
typedef boost::function<IBaseClass*(std::unique_ptr<IBaseClass>&, std::unique_ptr<IBaseClass>&)> IBaseClassConstructorFunc_factory;

// Dummy base factory - no template  
class UBaseClassTemplateFactory
{
public:
};

template<typename T>
class UClassFactoryTemplate : public UBaseClassTemplateFactory
{
private:
	static std::map<string, IBaseClassConstructorFunc_factory> ClassFactoryTemplateMap; // Unique Classes only


public:
	UClassFactoryTemplate();
	__forceinline static UClassFactoryTemplate*Get()
	{
		static UClassFactoryTemplate<T> SingletonInstance;
		return &SingletonInstance;
	}

	static std::unique_ptr<IBaseClass<T>> CreateClassTemplatized(string ClassString, std::unique_ptr<IBaseClass> LeftArgument, std::unique_ptr<IBaseClass> RightArgument);
};


// This type def we keep for non templatized base class
typedef boost::function<UBaseClassTemplateFactory*()> ClassFactoryTemplate_factory;


/* This is the instance class that resolves the classes as well as the concrete datatype to be used in UClassFactoryTemplate*/
class UClassFactory
{

private:
	UClassFactory();
	static std::map<EMyDataTypes, ClassFactoryTemplate_factory> ClassDataTypeTemplateFactoryMap;
	

public:

	__forceinline static UClassFactory *Get()
	{
		static UClassFactory SingletonInstance;
		return &SingletonInstance;
	}

	static std::unique_ptr<IBaseClass> CreateConcreteClass(string ClassString, std::unique_ptr<IBaseClass> LeftVal, std::unique_ptr<IBaseClass> RightVal, EMyDataTypes someEnumVal = EMyDataTypes::INT8);

};

Finally, in ClassFactory.cpp

#include "ClassFactory.h"
#include <boost/bind.hpp>

/*static, but non-const data members should be defined outside of the class definition
*and inside the namespace enclosing the class. The usual practice is to define it in
*the translation unit (*.cpp) because it is considered to be an implementation detail.
*Only static and const integral types can be declared and defined at the same time (inside class definition):*/

template<typename T>
std::map<string, IBaseClassConstructorFunc_factory> UClassFactoryTemplate<T>::ClassFactoryTemplateMap;
std::map<EMyDataTypes, ClassFactoryTemplate_factory> UClassFactory::ClassDataTypeTemplateFactoryMap;


template<typename T>
inline UClassFactoryTemplate<T>::UClassFactoryTemplate()
{
	ClassFactoryTemplateMap[MyClassesNamespace::CLASS_A] = boost::bind(boost::factory<ConcreteClassA<T>*>(), _1, _2);
	ClassFactoryTemplateMap[MyClassesNamespace::CLASS_B] = boost::bind(boost::factory<ConcreteClassB<T>*>(), _1, _2);
	ClassFactoryTemplateMap[MyClassesNamespace::CLASS_C] = boost::bind(boost::factory<ConcreteClassC<T>*>(), _1, _2);
}

template<typename T>
std::unique_ptr<IBaseClass<T>> UClassFactoryTemplate<T>::CreateClassTemplatized(string ClassString, std::unique_ptr<IBaseClass> LeftArgument, std::unique_ptr<IBaseClass> RightArgument)
{
	std::unique_ptr<IBaseClass<T>> someTemplatizedDataTypeInstance{ ClassFactoryTemplateMap.at(ClassString) (LeftArgument,RightArgument) };
	return someTemplatizedDataTypeInstance;
}

UClassFactory::UClassFactory()
{
	ClassDataTypeTemplateFactoryMap[EMyDataTypes::INT8] = boost::bind(boost::factory<UClassFactoryTemplate<int>*>());
	ClassDataTypeTemplateFactoryMap[EMyDataTypes::FLOAT8] = boost::bind(boost::factory<UClassFactoryTemplate<float>*>());
	ClassDataTypeTemplateFactoryMap[EMyDataTypes::FLOAT16] = boost::bind(boost::factory<UClassFactoryTemplate<double>*>());
}

std::unique_ptr<IBaseClass> UClassFactory::CreateConcreteClass(string ClassString, std::unique_ptr<IBaseClass> LeftVal, std::unique_ptr<IBaseClass> RightVal, EMyDataTypes someEnumVal)
{
	std::unique_ptr<UBaseClassTemplateFactory>  BaseOperatorTempFactory{ ClassDataTypeTemplateFactoryMap.at(someEnumVal) };
	return BaseOperatorTempFactory->Get()::CreateClassTemplatized(ClassString, LeftVal, RightVal);
}

The question now is, the above code does not even compile let alone run, it says abstract class cannot be instantiated for the templatized map. I just want the UClassFactory to return me correct instantiated class like A,B,C based on a string map with correct datatypes based on an enum. How do I achieve this combination? I wonder what is the correct syntax? Or is my approach inherently flawed? Or there is a nice way to instantiate classes with factory pattern and different datatypes? Please let me know any suggestions/ comments.

Thanks

Alam