Search code examples
recursionc++11variadic-templatestypeid

recursive variadic template to print out the contents of a parameter pack


How is it possible to create a recursive variadic template to print out the contents of a paramater pack? I am trying with this, but it fails to compile:

template <typename First, typename ...Args>
std::string type_name () {
    return std::string(typeid(First).name()) + " " + type_name<Args...>();
}
std::string type_name () {
    return "";
}

How shall I end the recursion?


Solution

  • You need to use partial specialisation to end the recursion, but since you can't partially specialise free functions in C++, you need to create an implementation class with a static member function.

    template <typename... Args>
    struct Impl;
    
    template <typename First, typename... Args>
    struct Impl<First, Args...>
    {
      static std::string name()
      {
        return std::string(typeid(First).name()) + " " + Impl<Args...>::name();
      }
    };
    
    template <>
    struct Impl<>
    {
      static std::string name()
      {
        return "";
      }
    };
    
    template <typename... Args>
    std::string type_name()
    {
        return Impl<Args...>::name();
    }
    
    int main()
    {
      std::cout << type_name<int, bool, char, double>() << std::endl; // "i b c d"
      return 0;
    }
    

    That first declaration of Impl is just a workaround for a shortcoming in g++ 4.6 (and below). It won't be necessary once it implements variadic templates correctly.

    Check it out in action at ideone.com