简体   繁体   中英

function Template with explicit type names

I've been reading some pages about template s.

I see that, template s are used like this:

template <typename T>
T func(T a) {...}

So it's for providing flexibility to use the same code for different type of variables. And also, we can use specialization which seems only applies to class, it's like:

template <> class A<int> {....}

But I didn't find the kind of use like this:

template<int N, bool isVertical, bool isFirst, bool isLast>
static void filter(int bitDepth, Pel const *src, int srcStride, 
                   short *dst, int dstStride, int width, 
                   int height, short const *coeff);

It's called like this:

filter<N, false, true, true>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);

In this code, template is given real and absolute types, IMHO, we can just add another four parameters into filter's parameter list instead of using template.

So, why template are used like this?

template s are not functions. template s are factories of functions, where the arguments determine which function is produced.

( template functions also have type deduction based off of arguments, but that just determines which function is produced by the template function factory).

So this:

template<int N, bool isVertical, bool isFirst, bool isLast>
static void filter(int bitDepth, Pel const *src, int srcStride, 
               short *dst, int dstStride, int width, 
               int height, short const *coeff);

doesn't define one filter function, but an entire family of such functions.

The arguments within the <> after filter are the arguments passed to the template function factory to determine which function is actually produced.

When these functions are produced by the factory (at compile time), the values passed into the template function factory are known. So optimizing around these constants is really easy.

It is true that inlining and the as-if rule can allow compilers to take literal arguments, deduce that a given argument is a compile time constant, and compile a function with that constant included -- but this technique is both fragile and limited.

With a template factory produced function, it is an actual function. So you can store a pointer to it and pass it around as a stateless function.

For a concrete example, suppose you want to process an image. Now the practical way to process an image is to set up a scanline based function with some data, then iterate over the scanlines of the image, passing each one to the scanline based function.

On the other hand, many image transformations are per-pixel transformations. Writing all of the optimized looping over those pixels in each image transformation function results in lots of copy-paste code. But you cannot afford to pass in a pointer to a pixel based operation to a scanline processing function -- the overhead to dereference a pointer is more than a bit high when compared to typical per-pixel operations.

So instead you create a template function factory that takes a per-pixel function at compile time, and wraps it up in the iteration over pixels code. The overhead just goes away.

What more, instead of a pixel operation you might pass in another template function factory (via a template class ), so you can do things like set if you are doing SSE type assembly, how many pixels the per-pixel operation should process at a time, etc.

The result can be a bunch of code that is written with if s, seemingly full of branches and conditionals, but actually compiles down to a nearly completely flat and branchless scanline operation when you pass in all of the parameters as template arguments.

In short, template s help solve problems that traditionally where solved via code generation -- be it macros or 3rd party tools. They are sufficiently powerful and convenient that people are using them for code generation in cases where you would never have bothered before, like generating custom containers for each user type, custom search algorithms, hashing algorithms, iteration, for loops, and a myriad of other tomfoolery.

Everything that template s can do can be done without them, but that is not surprising: beware the Turing tar pit, where everything is equivalent, but nothing of import is easy. template s make a certain kind of code generation easy .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM