3

The following code prints out the string "T" not the actual typename when the templated function is called. Is there a way to get the real typename without adding anything to the types being templated?

#define stringify(a) #a
#define tostring(a) stringify(a)

template <typename T>
void function_foo(T a, T b)
{
    cout << tostring(T) << endl;
    ...
}
grokus
  • 18,046
  • 9
  • 29
  • 35

4 Answers4

3

Templates don't work like that. In your template T specifies a type, and not a sequence of tokens:

typedef int lolztype;
typedef int lulztype;

function_foo<lolztype>(0, 0);
function_foo<lulztype>(0, 0); // calls the *same* template

There is no way to get lolztype or lulztype respectively. What you could try is using typeid(T).name(), but that isn't very helpful because it isn't required to be human readable and not even required to be distinct for each type.

You could try using geordi's file type_strings.hpp, which can print out a human readable string when compiled with GCC.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • do you mean that two types that may have identical internal binary representation, but distinct definitions/declarations might have the same typeid().name() ? – Stephane Rolland Dec 23 '10 at 14:38
  • @Stephane it's completely unspecified. – Johannes Schaub - litb Dec 23 '10 at 14:42
  • @Stephane: he means that (for example) `int` and `std::vector` might have the same `type_info::name()`. – Steve Jessop Dec 23 '10 at 17:17
  • okay, so there's no garanty of interesting result depending on the implementation of the compiler. – Stephane Rolland Dec 23 '10 at 17:21
  • @StephaneRolland As a programmer, you usually try to stay away from "interesting" results :) Myself, I would find it pretty interesting if `int` and `std::vector` _did_ have the same `type_info::name()`. – HelloGoodbye Oct 29 '18 at 10:03
  • @HelloGoodbye Interesting? In which way? Maybe you mean delighting, funny, curious, for a few seconds maybe. At most :) – Stephane Rolland Oct 29 '18 at 13:41
  • @StephaneRolland What I mean is, if someone says that a result is _interesting_, it probably means that the result was unexpected. If you expected the result, why would it be interesting? Personally, I wouldn't expect `int` and `std::vector` to have the same `type_info::name()`, so if they did I would find that interesting. – HelloGoodbye Oct 29 '18 at 18:18
1

use:

#include <typeinfo>

template <typename T>
void function_foo(T a, T b)
{
    cout << typeid(a).name() << endl;
    ...
}

what typeid().name() returns is plateform dependent but is a string may represent your type.

Stephane Rolland
  • 38,876
  • 35
  • 121
  • 169
  • This is actually technically incorrect. From [the manual](http://www.cplusplus.com/reference/typeinfo/type_info/name/): "Returns a null-terminated character sequence that may identify the type.". So it may or may not actually "represent your type". – Chris Kitching May 25 '17 at 04:20
  • 1
    @ChrisKitching If the string can be used to identify the type, doesn't it technically represent the type? – HelloGoodbye Oct 29 '18 at 10:44
  • @ChrisKitching I have been told several times not to refer to www.cplusplus.com documentation which may not be of optimal quality. Check https://en.cppreference.com/w/cpp/types/type_info/name . – Stephane Rolland Oct 29 '18 at 13:19
1

There's the typeid operator. But note that the name() string is implementation-defined. In particular, it often involves some name mangling. Some implementations also provide another public method to get a "prettier" string; check your <typeinfo> header.

#include <typeinfo>
template <typename T>
void function_foo(T a, T b)
{
    std::cout << typeid(a).name() << std::endl;
    // ...
}
aschepler
  • 70,891
  • 9
  • 107
  • 161
1

Your only choice is to define this reflection on your own, perhaps via an interface that returns the string representation of its concrete type.

struct my_type : public reflects {
    my_type();
    static const std::string& type_name = "my_type";
};
wilhelmtell
  • 57,473
  • 20
  • 96
  • 131