Jump to content
  • Advertisement
Sign in to follow this  
ozzyf

Calling a function in a derived class from a template

This topic is 888 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a template class that I am writing that goes through an array of type T (say a float):

template <class T> class Field
{
public:
	void Iterate()
	{
		for (unsigned int n=0; n<10; n++)
		{
			DerivedFunc(n);
		}
	}
	
	T m_Data[10];
}

class GreenField : public Field<int>
{
public:
	void DerivedFunc(unsigned int n)
	{
		m_Data[n] = m_Data[n] + 1;
	}
}

What I want to do is call a function in the derived GreenField, that operates on the data in the base template class. How should I be going about this? :wacko:

 

I also want to make sure the compiler to be able to optimize out the function call, and inline it, rather than passing any pointers to objects / virtual functions, as this is part of the reason for using a template...

Share this post


Link to post
Share on other sites
Advertisement

Did you actually try what the compiler does in the simple virtual function case?

Also, did you check what the performance gain is?

 

Compilers encounter a lot more code with virtual methods in derived classes than they encounter cumbersome "work around virtual function" templates. Likely they recognize the former much better than the latter, so your perceived speed up may in fact be a slow down, since you disable optmizations for the comon case.

 

 

Also if 10 function calls are a performance problem, something is very wrong. The only way to get that is by having virtually empty DerivedFunc, at which point you may want to ask yourself if that should really be a separate method, I think. You can always also move the loop into the derived class, which means 1 virtual function call instead of 10.

 

Why not simply start with a plain derived class, see what happens, and when you run into performance problems, optimize the point where it matters?

 

Share this post


Link to post
Share on other sites

The code here is just a simplified example. I didn't realise the compiler could optimize out virtual functions and inline them, will have to investigate!  :lol:

 

I have found a possible solution to exactly what I was looking for : "The curiously recurring template pattern."

 

This code I copied from another forum but shows the idea:

template <typename ID, typename object, typename T>
class Foo
{
    public:
       ...
       void AddRef(ID theID) {
           ...
           static_cast<T*>(this)->internalAddRef(theID);
           ...
       }
};
 
class Derived : public Foo<string, Object, Derived>
{
    public:
        ...
        void internalAddRef(string ID) {
            ...
        }
};

If it does allow the compiler to inline that will be exactly what I was after. 

Share this post


Link to post
Share on other sites
Compilers encounter a lot more code with virtual methods in derived classes than they encounter cumbersome "work around virtual function" templates. Likely they recognize the former much better than the latter, so your perceived speed up may in fact be a slow down, since you disable optmizations for the comon case.

 

[Edited, nevermind, I'm thinking of preprocessor macros] It's actually pretty straightforward to see the exact code generated, at least in visual studio you can write the template output to a file.

 

I don't look at templates as an optimization or pessimization inherently. You can avoid the virtual function indirection with CRTP, yes. But you are also writing "generic" code which means you are specifically *not* optimizing for the types where you try to apply that code. It can go both ways. Think of the CRTP (aka compile-time polymorphism) as C++'s way to do duck typing, vs. paying a runtime cost for vtable polymorphism. You need to ask yourself the question of whether or not you need the polymorphism at runtime.

Edited by y2kiah

Share this post


Link to post
Share on other sites

[...]


template <typename T> class Field
{
public:
	template <typename Functor> void Iterate(Functor f)
	{
		for (unsigned int n=0; n<10; n++)
		{
			f(m_Data[n] /* or whatever seems reasonable */);
		}
	}
	
	T m_Data[10];
};
That's a lot more C++ instead of doing some kind of inheritance hierarchy and the compiler has a lot of practice optimizing it. Even better would be something like this:
template <typename T> class Field
{
public:
	T* begin() { return &m_Data[0]; }
	T* end() { return begin() + 10; }

	T m_Data[10];
};
Now it works with all those standard library algorithms, including ranged for. You might need a few additional typedefs as well, but the real question is, why don't you use std::array which already does what you try and more. Edited by BitMaster

Share this post


Link to post
Share on other sites

In all honesty, the "The curiously recurring template pattern." was fairly old, and it was just a way to show off template programming. Back then templates were really underused. Now with the introduction of the standard template library it's most common use case is usually for Template Metaprogramming, or stacking up data of varying types in linear memory.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!