title: Implementing pImpl based wrapper around a class using variadic template functions
body: <h1>Summary</h1>
  <p>I'm writing a library and a client application. In the library I'm trying to write a wrapper around another statically linked third-party library (specifically, <a href="https://github.com/gabime/spdlog" rel="noreferrer">spdlog</a>) and am trying to use the pImpl idiom to completely hide it from the client application. The problem is that the third-party library uses variadic template functions, and so I need to in my library too.</p>
  <h1>Background</h1>
  <p>My first attempt at a wrapper was pretty thin and straight forward, but then I was getting &quot;No such file or directory&quot; errors in my client application because the third-party header was being included in my library's header.</p>
  <p>I next tried to create a pImpl class and got that to compile, but again in the client I was getting &quot;undefined reference&quot; linker errors.</p>
  <p>Pulling the source code for the implementation into the header for my wrapper puts me right back at the initial &quot;No such file&quot; problem. After researching this I'm starting to think making a wrapper around variadic templates isn't possible, but I'm not sure. This is the first time I've ever tried to make a variadic function/template.</p>
  <h1>Example Code</h1>
  <p>Here's how my project currently stands:</p>
  <p>Almost all namespaces, function names, headers, etc. have all been edited (or removed) for brevity and clarity.</p>
  <h2>Client Application - sandbox.cpp</h2>
  <pre><code>#include &quot;sandbox.h&quot;
  #include &lt;logger.h&gt;  //  &lt;-- This is all I want clients to see.
  
  int Sandbox::run() {
      LOG_INFO(&quot;Hello World!&quot;);        // My library is providing this.
      LOG_INFO(&quot;Hello {}&quot;, &quot;indeed!&quot;); // And, this variable input function.
      return 0;
  }
  </code></pre>
  <h2>My Library - logger.h</h2>
  <pre><code>class LoggerImp;  // Forward declaration of implementation.
  
  class LIB_EXPORT Logger {
    public:
  
      /* Constructors, destructor, etc. */
  
      template &lt;typename... Args&gt;
      void info(const char * fmt, Args &amp;... args);
  
      void info(const char * msg) { this-&gt;info(&quot;{}&quot;, msg); }
  
      /* Other logging functions: trace, error, etc. */
  
    private:
      LoggerImp * _imp;
  };
  
  static Logger coreLogger(&quot;Core&quot;);
  static Logger clientLogger(&quot;App&quot;);
  
  #define LOG_INFO(args...) clientLogger.info(args)
  /* Other such convenience definitions. */
  </code></pre>
  <h2>My Library - logger.cpp</h2>
  <pre><code>#include &quot;logger.h&quot;
  #include &quot;loggerimp.h&quot;
  
  Logger::Logger(std::string name) { _imp = new LoggerImp(name, this); }
  Logger::~Logger() { delete _imp; }
  
  template &lt;typename... Args&gt;
  void Logger::info(const char * fmt, Args &amp;... args) {
      _imp-&gt;info(fmt, args...);
  }
  </code></pre>
  <h2>My Library - loggerimp.h</h2>
  <pre><code>#include &quot;logger.h&quot;
  #include &lt;spdlog/spdlog.h&gt;
  #include &lt;spdlog/sinks/stdout_color_sinks.h&gt;
  
  class LoggerImp {
    public:
      explicit LoggerImp(string name, Logger * pubInterface) :
          _pubInterface(pubInterface) {  // Back pointer.
          _sink   = make_shared&lt;spdlog::sinks::stdout_color_sink_mt&gt;();
          _logger = make_shared&lt;spdlog::logger&gt;(name, _sink);
          spdlog::initialize_logger(_logger);
          // The above three lines create the actual logging object
          // that my library is wrapping and hiding from its clients.
      }
  
      template &lt;typename... Args&gt;
      inline void info(const char * fmt, const Args &amp;... args) {
          _logger-&gt;info(fmt, args...);  // Third-party logging function.
      }
  }
  </code></pre>
  <h1>Expected Results</h1>
  <p>As mentioned above I just want clients of my library to be able to include headers like <code>&lt;logger.h&gt;</code> and not need to configure their projects to find and handle all of my library's dependencies as well, but since I'm currently using a third-party tool that uses variadic templates I'm not seeing any way that I can hide that from my clients given the, um... &quot;not a real function&quot; nature of templates.</p>