0

TL;DR

How do I initialize a static template variable that will have a different value for each class that inherits from it?

Not TL;DR

I have the following code in my project, that is intended to identify the class created with a template parameter, to make sure no one else creates it (in a different part of the code, not represented here):

template <typename T>
class foo
{
   ... some other code and methods ...   
   
   virtual const char* getId() 
   {
      return idString;
   }

   static const char* const idString;
};

I would like to initialize idString, so as we know and saw here and here, I want to initialize the variable in the header file underneath the class definition, where the above class declaration is located:

template <typename T>
const char* const idString = strcat("foo::", #T);

or something like that, because this does not compile. This is done so that the following code:

class bar : public foo<S>
{
   ...some other code...
   
   const char* getId()
   {
      return idString;
   }

   static const char* const idString;
};

will generate "foo<S>" when getId() is called with a bar class instance and "foo<T>" when the base class getId() is called, by hiding the const variable idString of foo (this is, of course, not an override).

Thing is, strcat is not a something the compiler can calculate at run time, so this doesn't work well. Currently, the only thing that will work, but has backward compatibility issues is adding a const char* class parameter to the foo class definition, but than each instance of foo<P> will have to beconme foo<P, "foo::P"> manually, and will break previous code uses.

I have read a few solutions that looked like this which rely on RTTI, but this isn't the case here.

Thought of using a macro for this, since macros are pre-compilation and can "know" the string representation from the text written, but can't get the syntax properly. Any other suggestions will be incredible! Thank you.

mayanco
  • 1
  • 1
  • Your question is wage and I personally don't understand what is the problem. Please edit your question and use easier language to describe the situation. – newbie Apr 07 '21 at 05:56
  • Also please note that you can never instantiate a template like ```foo

    ``` because ```"foo::p"``` is not valid parameter for the template and string literals can never be used for this purpose .

    – newbie Apr 07 '21 at 06:00
  • You have to rely on RTTI. There is no other way to do it. – n. m. could be an AI Apr 07 '21 at 06:02
  • @newbie you're right about the `"foo::P"` remark, that was actually psuedo-code for saying I will add a template parameter. About the question being not understandable - it's a complex question, so a complex explanation was unfortunately needed, sorry about that. I really put an effort in describing the situation. – mayanco Apr 07 '21 at 06:07
  • I added somewhat of a TL;DR section to clarify my question perhaps, but it lacks some cases that answering the TL;DR question will not answer my bigger question – mayanco Apr 07 '21 at 08:01
  • Does [this](https://stackoverflow.com/a/59522794/2752075) answer your question? – HolyBlackCat Apr 07 '21 at 09:07
  • @HolyBlackCat actually it does, but I did find a simpler way and marked it as an answer, but your reference would work on any project that has C++11 and above only, while I don't (I didn't write that on purpose because I didn't want to limit the answer to not using `constexpr`) – mayanco Apr 07 '21 at 11:01

1 Answers1

0

Solved it myself, just opened a namespace in the inherited class's header file and initialized the static member there:

bar.h:

namespace foo
{
    const char* const foo<bar>::idString = "foo<bar>";
}

and for other bars that didn't implement this they get a default value defined in foo's class.

mayanco
  • 1
  • 1