Is there a way to partially specialize a template with parameter packs for a recursive function?

parameter packs not expanded with
c++ variadic templates unpack
c iterate over parameter pack
parameter pack must be expanded in this context
parameter pack expansion
c variadic function
recursive template function c++
template template parameter

I'm trying to make a print function in C++ that takes in variable numbers of arguments and prints them each on their own line, like:

template<typename Ty, typename... Types>
void println(Ty cur_line, Types... other_lines)
{
    std::cout << cur_line << '\n';
    println(other_lines);
}
void println() { std::cout << std::flush; }

However, if Ty happens to be a std::vector<std::string>, I want to treat it differently (because I want to print every element of the vector on its own line). I looked into partial specialization, but there doesn't seem to be much that I could find on doing so with parameter packs. Here's what I tried:

template<typename Ty, typename... Types>
void println(Ty cur_line, Types... other_lines)
{
    std::cout << cur_line << '\n';
    println(other_lines);
}

template<typename... Types>
void println<std::vector<std::string>, Types...>
    (std::vector<std::string> cur_line, Types... other_lines)
{
    for (const auto& line : cur_line)
    {
        std::cout << line << '\n';
    }
    println(other_lines);
}

void println() { std::cout << std::flush; }

However, I'm getting an MSVC error C2768: "'println': illegal use of explicit template arguments". Any suggestions or solutions would be warmly welcomed! For reference, I'm using Visual Studio 2019 Preview and its corresponding compiler version.

A simpler way would be to have a print function and overload that:

template < typename T >
void print(const T& line)
{
    std::cout << line << '\n';
}

template < typename T >
void print(const std::vector<T>& line)
{
    for (const auto& element : line)
    {
        print(element);
    }
}

template<typename Ty, typename... Types>
void println(Ty cur_line, Types... other_lines)
{
    print(cur_line);
    println(other_lines);
}

void println() { std::cout << std::flush; }

Parameter pack(since C++11), A template parameter pack is a template parameter that accepts zero or more template arguments (non-types, types, or templates). A function� The second overload contains a separate template parameter for the head of the arguments and a parameter pack, this allows the recursive call to pass only the tail of the parameters until it becomes empty. Targs is the template parameter pack and Fargs is the function parameter pack See also

You can do it like this:

/* main.cpp */

#include <iostream>
#include <vector>
#include <string>

using namespace std;

template <class T>
void PrintLine(const T &t)
 {
  cout << t << endl ;
 }

template <class T>
void PrintLine(const vector<T> &t)
 {
  for(auto &obj : t ) PrintLine(obj);
 }

template <class ... TT>
void PrintLines(const TT & ... tt)
 {
  ( PrintLine(tt) , ... );
 }

/* main() */

int main()
 {
  vector<string> list{"a","b","c"};

  PrintLines(1,2,3,list);

  return 0;
 }

Variadic templates (C++11), The template parameter pack is expanded by the function parameter pack. The following example shows how to use partial specialization for variadic templates: member of the parameter pack in the first step, and recursively instantiate the� Note, by the way, that you can also partially specialize on template arguments--for instance, if you had a fixedVector type that allowed the user of the class to specify both a type to store and the length of the vector (possibly to avoid the cost of dynamic memory allocations), it might look something like this:

You can't partially specialize a function template, but you can overload it. Create a new overload of println that takes a std::vector<std::string> as the first argument and a general pack as the rest. Then do the special handling for the vector arg and forward the rest as before. Now your vectors will always be caught by the overload.

Parameter pack, explicit (full) specialization Template parameter pack (appears in a class template and in a function A variadic class template can be instantiated with any number of template arguments: Reason: a few words about partial specializations and other ways to access Fargs) // recursive variadic function { for ( ; *format ! A class template can be partially specialized and/or fully specialized. [1] A function template can only be fully specialized, but because function templates can overload we can get nearly the same effect via overloading that we could have got via partial specialization. The following code illustrates these differences:

How to unroll a parameter pack from right to left, Specifically, C++ template partial specialization: Why cant I match the last type to do recursive parameter pack unrolling, which is sort of the whole point here. A function with the same name and the same argument list as a specialization is not a specialization (see template overloading in function template) . An explicit specialization of a function template is inline only if it is declared with the inline specifier (or defined as deleted), it doesn't matter if the primary template is inline.

[PDF] Variadic Templates for C++0x, form of partial function application for C++, tuple libraries [3,4], libraries generaliz- ing C++ show how manipulating the variadic template argument lists may require specialization matches and ends the recursive chain of instantiations. A variadic function template is defined by using a parameter pack in the type of the. If the default is specified for a template parameter of a primary class template, primary variable template, (since C++14) or alias template, each subsequent template parameter must have a default argument, except the very last one may be a template parameter pack. In a function template, there are no restrictions on the parameters that follow

Homogeneous variadic function parameters, This paper seeks to expand the usefulness of variadic templates by allowing variadic The term homogeneous function parameter pack refers to a The recursion approach advertises a function that can take variadic arguments of any it is not possible to partially or explicitly specialize an alias template. The way I interpret this is that there is nothing wrong in allowing function template partial specialization in C++, but we don’t know if it will be in the language one day. Related articles: Template Partial Specialization in C++

Comments
  • function templates cannot be partially specialized, period. You'll need some user defined type magic for the required effect.
  • @TanveerBadar cppreference on partial specialization
  • Yes, my point too. You are trying to do that to functions. That is not supported.