CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Dec 2010
    Posts
    907

    How can I create a template method in a C++ class?

    Code:
    class A {
    
    public:
    template<class T> 
    	ObjectsBase* createObject(T* objType, Ogre::String name, Ogre::Vector3 position);
    };
    
    template<class T>
    ObjectBase* A::createObject(T* objType, Ogre::String name, Ogre::Vector3 position);
    My goal is to create any ObjectBase* derived object and return it to class A....
    Any ideas?
    Thanks
    Jack

  2. #2
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: How can I create a template method in a C++ class?

    you need to define the 'body' of the templated memberfunction in a public header.

    so you either add that code inline in the class definition
    Code:
    class A {
    public:
    template<class T> 
    	ObjectsBase* createObject(T* objType, Ogre::String name, Ogre::Vector3 position)// No ; here
    
         {
                // Add implementation here
         }
    };
    or you add the implementation outside of the class definition (but still in a header)
    Code:
    template<>
    ObjectBase* A::createObject<class T>(T* objType, Ogre::String name, Ogre::Vector3 position)
    {
       // Add implementation here
    }
    As above, it's a general implementaiton
    You can specialise by replacing <class T> by <class MyClass> and implement the function specific for a MyClass. This is handy if you can't generalize it for every possible template parameter.

    In the case of a specialization, if so desired, you can define the prototype in a header, and implement in a .cpp.
    Last edited by OReubens; July 8th, 2014 at 08:23 AM.

  3. #3
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158

    Re: How can I create a template method in a C++ class?

    Apart from what OReubens suggested, I recommend not to return a raw pointer to the object, but a smart pointer. This relieves the caller of createObject from the question of the ownership of the object pointed to.

  4. #4
    Join Date
    Dec 2010
    Posts
    907

    Re: How can I create a template method in a C++ class?

    Thanks OReubens and Richard,
    It works as expected now.

    Code:
    template<class T> 
    ObjectBase* createObject(T* objType, Ogre::String name, Ogre::Vector3 position) {
    		if(mDetourCrowd[name.c_str()]->getNbAgents() >= mDetourCrowd[name.c_str()]->getMaxNbAgents()) {
    			Ogre::LogManager::getSingletonPtr()->logMessage("Error: Cannot create crowd agent for new Object. Limit of "+Ogre::StringConverter::toString(mDetourCrowd[name.c_str()]->getMaxNbAgents())+" reached", Ogre::LML_CRITICAL);
    			throw new Ogre::Exception(1, "Cannot create crowd agent for new Object. Limit of "+Ogre::StringConverter::toString(mDetourCrowd[name.c_str()]->getMaxNbAgents())+" reached", "OgreRecastApplication::createObject("+name+")");
    		}
    
    		ObjectBase* obj = new T(name, mSceneMgr, mDetourCrowd[name.c_str()], mDebugDraw, position);
    		mObjects[name.c_str()] = obj;
    		return obj;
    	}
    Do I call this method this way?
    Code:
    obj = createObject(new Worker(), "name", Ogre::Vector3(0,0,0))
    Jack
    Last edited by lucky6969b; July 9th, 2014 at 12:10 AM.

  5. #5
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158

    Re: How can I create a template method in a C++ class?

    Quote Originally Posted by lucky6969b View Post
    Thanks OReubens and Richard,
    Code:
    obj = createObject(new Worker(), "name", Ogre::Vector3(0,0,0))
    This leaves you with a memory leak. The new Worker object is a temporary object you can never delete. Since you are not using it anyway, your method could be defined like this
    Code:
    template<class T> 
    std::shared_ptr<ObjectBase> createObject(Ogre::String name, Ogre::Vector3 position)
    {
        std::shared_ptr<ObjectBase> obj( new T(name, mSceneMgr, mDetourCrowd[name.c_str()], mDebugDraw, position));
        mObjects[name.c_str()] = *obj;
        return obj;
    }

  6. #6
    Join Date
    Dec 2010
    Posts
    907

    Re: How can I create a template method in a C++ class?

    Thanks, Richard.
    Code Updated.
    Jack

  7. #7
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: How can I create a template method in a C++ class?

    Look how much easier to read your code becomes with a few local variables. You should really stop copy-pasting source code; it's a very bad habit.
    Code:
    template<class T> 
    ObjectBase* createObject(Ogre::String name, Ogre::Vector3 position)
    {
    	auto detour = mDetourCrowd[name.c_str()];
    	if (detour->getNbAgents() >= detour->getMaxNbAgents()) {
    		const auto msg = "Cannot create crowd agent for new Object. Limit of "
    			+ Ogre::StringConverter::toString(detour->getMaxNbAgents())
    			+ " reached";
    		Ogre::LogManager::getSingletonPtr()->logMessage("Error: " + msg, Ogre::LML_CRITICAL);
    		throw new Ogre::Exception(1, msg, "OgreRecastApplication::createObject(" + name + ")");
    	}
    
    	ObjectBase* obj = new T(name, mSceneMgr, detour, mDebugDraw, position);
    	mObjects[name.c_str()] = obj;
    	return obj;
    }
    Also, it's best to throw exceptions by value and catch them by const reference. So unless you are working within a framework that requires throwing dynamically allocated exceptions, I would change that.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured