6

I have a class that is suppose to be a base class:

template<int ID>
class BaseClass { ... };

How can I make a compile-time error appear if two classes try to inherit form this base class using the same value of ID. That is - this code is suppose to work:

class A : BaseClass<1> { ... }
class B : BaseClass<2> { ... }

But this code is suppose to cause an error:

class A : BaseClass<1> { ... }
class B : BaseClass<1> { ... }

How can one achieve this? Does BOOST_STATIC_ASSERT help?

Naveen
  • 74,600
  • 47
  • 176
  • 233
Bartłomiej Siwek
  • 1,447
  • 2
  • 17
  • 26
  • You mean `BaseClass` instead of `ID` in the second and third snippet, I assume? – Thomas Mar 14 '11 at 12:23
  • @Bartłomiej: I think you wanted to write `class A : BaseClass<1> { ... }` instead of `class A : ID<1> { ... }`. – Nawaz Mar 14 '11 at 12:25
  • You are right - it was suppose to be `BaseClass`. My mistake. – Bartłomiej Siwek Mar 14 '11 at 12:26
  • 2
    Just a question, when do we benifit from this? I mean why do you want to do that? – Tamer Shlash Mar 14 '11 at 12:27
  • I think it can even be proven that it's impossible. First of all you cannot do it even with a non-template class. And here's why. If it can be done once, you can just copy all the same files, just change the names of the derived classes and you'll end up with two implementations. Bare in mind that modularity in C/C++ is achieved though direct text-based inclusion. – julx Mar 14 '11 at 12:31
  • We would benefit from this in a scenario described in this question [link](http://stackoverflow.com/questions/2850213/dynamically-register-constructor-methods-in-an-abstractfactory-at-compile-time-us) to make sure no two messages have the same id. – Bartłomiej Siwek Mar 14 '11 at 13:55

3 Answers3

1

I think that is impossible.

If it were possible, then we can make compiler to generate error for the following code as well, which is conceptually equivalent to your code.

struct Base {};
struct OtherBase {};

struct A : Base {}; //Base is used here!
struct B : Base {}; // error - used base class. please use some other base!
struct C : OtherBase {}; // ok - unused based!
Nawaz
  • 353,942
  • 115
  • 666
  • 851
1

Just guessing, but in case you want to generate unique type ids, you may want to check out this and this question.

Community
  • 1
  • 1
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
0

I cannot think of any possible solution at compile-time, using C++.

I can think of a possible solution at launch-time (library initialization), but it would be limited.

class A: public Base<A,1> {};

We have Base register the correspondence between the id 1 and the class typeid(A) during the library initialization. If an id exists and the classes disagree, then stop the launch.

There is one caveat however:

class A: public Base<A,1> {};

class C: public A {};
class D: public A {};

Nothing prevents classes deriving from A to clash.

I can suggest static analysis: pick up a C++ parser and program a pre-commit hook that will check the modified files and see if they introduce a clash.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722