Home > OS >  Custom Types' Names Even For Templates With Variadic Arguments
Custom Types' Names Even For Templates With Variadic Arguments

Time:11-09

first of all we need a little introduction, so here we go. I'd like to write a functional struct that'll be able to retrieve name of a certain type, including templates. It'll return type's name from type_info or own defined custom name.

Here's a tiny logger which will need the name of a struct.

#define LOG(x) FunctionLog(#x, x)

template<typename _Ty>
void FunctionLog(const char* name, const _Ty& value)
{
    // TypeName'll be introduced later.
    std::cout << name << ": " << static_cast<const char*>(TypeName<_Ty>::c_Name) << " = " << value << '\n';
}
// Simple const char* wrapper, to easily concanate them with an operator|().
// I decided to use const char* instead of std::string due to memory.
struct CString
{
    const char* Content;

    explicit CString(const char* content)
        : Content(content) {}

    CString operator|(const CString& other)
    {
        return CString{ strcat(_strdup(Content), _strdup(other.Content)) };
    }

    operator const char*() const { return Content; }
};

template<typename _Ty>
struct TypeName
{
    static inline const CString c_Name = CString{ typeid(_Ty).name() };
}

// example of implementing that struct for std::vector<_Ty>
template<typename _Ty>
struct TypeName<std::vector<_Ty>>
{
    static inline const CString c_Name = CString{ "std::vector<" } | TypeName<_Ty>::c_Name | CString{ ">" };
};

And my problem is, how to make it work for std::tuples as I don't know how to do that, because the tuple has a various number of template arguments. And I would like it to look like so: std::tuple<int, int> -> std::tuple<int, int>, std::tuple<std::vector<int>, int> -> std::tuple<std::vector< int>, int>. So every argument of that tuple template should call corresponding TypeName<_Ty>.

If something is unclear, please ask as I could miss something.

CodePudding user response:

It seems you want something like (C 17):

template<typename ... Ts>
struct TypeName<std::tuple<Ts...>>
{
    static inline const CString c_Name =
       (CString{ "std::tuple<" } | ... | TypeName<Ts>::c_Name) | CString{ ">" };
};
  • Related