6

The question is rather simple: how to pretty print the name of a template parameter in a C++ class and assign it to a class variable at compile time ? It seems that both typeinfo (typeid) and boost::typeindex must be evaluated at runtime or as least some part of them. This apparently does not allow the compiler to completely solve a constexpr containing a call to one of this function.

template<typename T>
class X
{
   public:
      static const char * name = /* SOME C++ code transforming T in a string (either std::string or char */
};

What am I missing ? Is it only possible to generate a name at runtime ? In that case, does I really need an instantiated object ? It doesn't seem right to me, because the following perfectly work without any instance:

#include <iostream>
#include <string>
#include <boost/type_index.hpp>

using namespace std;

template<class T>
class X
{
        public:
                static std::string name()
                {
                        return boost::typeindex::type_id<T>().pretty_name();
                }
};

struct foobar {};

int main()
{
        cout << X<int>::name() << endl;
        cout << X<foobar>::name()<< endl;
}

So instead of having name() as a class method, I'd like to have it as a class variable.

David Bellot
  • 643
  • 7
  • 13
  • 1
    The _demangling_ is what cannot be done at compile time. You need a static initializer, but it will be called at runtime. – πάντα ῥεῖ May 16 '16 at 20:28
  • I don' think my question was a duplicate as I really want to do it at compile-time. However, the comment above gives a first clue why `constexpr` would fail. Can you tell me why the demangling cannot be done at compile time ? The compiler is supposed to know the type of the template parameter and generate a name. I'm not trying to get the type of an existing object but to transform a type name into a string (be it a std::string or a char *) – David Bellot May 16 '16 at 21:51
  • Well, I considered to reopen it and write my comment as an answer. If this would be more satisfying for you we could agree on this deal. In general I think it might be more useful for future research to have your question being linked to the duplicate, which well shows why it can't be done during compile time. – πάντα ῥεῖ May 16 '16 at 21:54
  • 1
    as you wish. I'm happy with your comment and the other answer. Thanks for your help: I know what I needed to know now. – David Bellot May 16 '16 at 22:01
  • You can see from the upvotes, that duplicate questions aren't be considered as unuseful in 1st place. These may be good signposts for future research as your question seems to be. – πάντα ῥεῖ May 16 '16 at 22:06
  • indeed. In fact I didn't find the answer you posted as duplicate first because I was not looking for the right information. So my duplicate question will help other to hop on the right answer. Tim Berners-Lee would be proud of this :-D – David Bellot May 17 '16 at 08:04

1 Answers1

0

I think, it is possible to use custom Type Traits. Please see the next example:

#include <iostream>
#include <string>

using namespace std;

//Using stub type traits
template <class T>
struct TypeTraits;

//your TypeTraits for specific types...
template<>
struct TypeTraits<int>
{
    constexpr static const char *name = "int";
};

template<class T>
class X
{
    public:
            constexpr static const char * name = TypeTraits<T>::name;
};

struct foobar {};

//TypeTraits for custom  foobar
template<>
struct TypeTraits<foobar>
{
    constexpr static const char *name = "foobar";
};


int main()
{
    //Now you can use static member here
    cout << X<int>::name << endl;
    cout << X<foobar>::name<< endl;
}

Also TypeTraits can be used (and expanded) for other purposes.

Sergei_Ivanov
  • 237
  • 1
  • 8