Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Counting With Template Metaprogramming?

I've been trying to think up a creative solution to this problem (on and off) for some time, but I have not as of yet been able to. I recently considered that it might be solvable with template metaprogramming, though I am not sure due to my relative lack of experience with the technique.

Is it possible to use template metaprogramming (or any other mechanism with the C++ language) to count the number of classes which are derived from some base class such that each derived class is given a unique, static class identifier?

Thanks in advance!

like image 839
Dan M. Katz Avatar asked Dec 21 '11 21:12

Dan M. Katz


People also ask

What is the point of template metaprogramming?

Template metaprogramming (TMP) is a metaprogramming technique in which templates are used by a compiler to generate temporary source code, which is merged by the compiler with the rest of the source code and then compiled.

What is a template coding?

Code Templates are reusable code snippets that allow you to quickly insert commonly used code fragments or surround given code fragment with a meaningful code block (example: try-catch statement).

What is TMP in C++?

Template meta-programming (TMP) refers to uses of the C++ template system to perform computation at compile-time within the code. It can, for the most part, be considered to be "programming with types" — in that, largely, the "values" that TMP works with are specific C++ types.


2 Answers

No. This is a problem that comes up in practice quite a lot, and as far as I'm aware there are only two solutions:

  1. Manually assign IDs to each derived class.
  2. Dynamically and lazily generate IDs non-deterministically.

The way you do the second one is something like this:

class Base
{
    virtual int getId() const = 0;
};

// Returns 0, 1, 2 etc. on each successive call.
static int makeUniqueId()
{
    static int id = 0;
    return id++;
}

template <typename Derived>
class BaseWithId : public Base
{
    static int getStaticId()
    {
        static int id = makeUniqueId();
        return id;
    }

    int getId() const { return getStaticId(); }
};

class Derived1 : public BaseWithId<Derived1> { ... };
class Derived2 : public BaseWithId<Derived2> { ... };
class Derived3 : public BaseWithId<Derived3> { ... };

This gives you unique IDs for each class:

Derived1::getStaticId(); // 0
Derived2::getStaticId(); // 1
Derived3::getStaticId(); // 2

However, those IDs are assigned lazily, so the order you call getId() affects the ID's returned.

Derived3::getStaticId(); // 0
Derived2::getStaticId(); // 1
Derived1::getStaticId(); // 2

Whether or not this is OK for your application depends on your particular needs (e.g. would be no good for serialisation).

like image 116
Peter Alexander Avatar answered Sep 23 '22 07:09

Peter Alexander


Is it possible to use template metaprogramming (or any other mechanism with the C++ language) to count the number of classes which are derived from some base class such that each derived class is given a unique, static class identifier?

No, there's no such mechanism. No matter what you do, you'll have to add "something" (most likely a macro) to every derived class manually to achieve something like that. See Qt 4 and Q_OBJECT macro. You could also make a macros for making derived classes, but this can't be done automatically.

You could however write your own C++ code preprocessor/analysis tool that scans source code you provided and then inserts necessary directives into source.

Also, RTTI provides name for every class. The problem is that this name is implementation-specific, so it isn't very useful.

like image 44
SigTerm Avatar answered Sep 24 '22 07:09

SigTerm