C++ 递归可变模板函数部分模板专门化的替代方法

C++ 递归可变模板函数部分模板专门化的替代方法,c++,c++11,template-specialization,variadic-templates,C++,C++11,Template Specialization,Variadic Templates,我正在使用递归变量模板编写sprintf()的替代方案,如中所述。我的目标是允许为用户定义的类型轻松添加自定义数据类型格式化程序。例如,如果基本实现如下所示: #include <iostream> #include <sstream> #include <wchar.h> #include <stdexcept> using std::wstring; using std::wstringstream; const wstring wspri

我正在使用递归变量模板编写sprintf()的替代方案,如中所述。我的目标是允许为用户定义的类型轻松添加自定义数据类型格式化程序。例如,如果基本实现如下所示:

#include <iostream>
#include <sstream>
#include <wchar.h>
#include <stdexcept>

using std::wstring;
using std::wstringstream;

const wstring wsprintf(const wchar_t *s)
{
    wstringstream outstream;
    while(*s)
    {
        if (*s == L'%' && *++s != L'%')
            throw std::runtime_error("invalid format string: missing arguments");
        outstream << *s++;
    }
    return outstream.str();
}

template<typename T, typename... Args>
const wstring wsprintf(const wchar_t *s, const T& value, const Args&... args)
{
    wstringstream outstream;
    while(*s)
    {
        if(*s == L'%' && *++s != L'%')
        {
            outstream << value << wsprintf(++s, args...);
            return outstream.str();
        }
        outstream << *s++;
    }
    throw std::runtime_error("extra arguments provided to wsprintf");
}
这样我就可以做到:

Foo bar;
wstring message = wsprintf("my foo tells me %s", bar);
但是,我编写这段代码的方式将不起作用,因为不允许函数的部分模板专门化(PTSF),如中所述

通常可替代PTSF的两种备选方案为:

  • 完全消除模板的使用,并使用重载函数
  • 创建静态类以包装函数的专用实现
  • 第一种选择似乎不可行,因为
    printf()
    的递归可变模板方法至少需要一个模板参数(可变参数包)

    当我尝试实现第二个备选方案时,我遇到了几个语法错误(内联为注释):

    名称空间wsprintf\u impl{
    结构wsprintf
    {
    静态常量wstring impl(常量wchar_*s)
    {
    河流外流;
    而(*s)
    {
    如果(*s==L“%”和&*++s!=L“%”)
    抛出std::runtime_错误(“无效格式字符串:缺少参数”);
    扩展
    结构wsprintf
    {
    静态常量wstring impl(常量wchar\u t*s、常量t和值、常量Args和…Args)
    {
    河流外流;
    而(*s)
    {
    如果(*s==L“%”和&*++s!=L“%”)
    {
    
    扩展问题是
    wsprintf
    同时声明为类和类模板。只需将其设置为类模板,第一种情况是不使用参数的专门化:

    template <typename...>
    struct wsprintf;
    
    template <>
    struct wsprintf<> // specialization for no arguments
    {
        // blah blah ... 
    };
    
    template< class T, class... Args> // oops, bad syntax here was
    struct wsprintf<T, Args...> // specialization for one or more args.
    {
        // blah blah ... 
    };
    
    模板
    结构wsprintf;
    样板
    struct wsprintf//无参数的专门化
    {
    //胡说八道。。。
    };
    template//哎呀,这里的语法不好
    struct wsprintf//一个或多个参数的专门化。
    {
    //胡说八道。。。
    };
    
    问题在于,
    wsprintf
    同时声明为类和类模板。只需将其设置为类模板,第一种情况是无参数专用化:

    template <typename...>
    struct wsprintf;
    
    template <>
    struct wsprintf<> // specialization for no arguments
    {
        // blah blah ... 
    };
    
    template< class T, class... Args> // oops, bad syntax here was
    struct wsprintf<T, Args...> // specialization for one or more args.
    {
        // blah blah ... 
    };
    
    模板
    结构wsprintf;
    样板
    struct wsprintf//无参数的专门化
    {
    //胡说八道。。。
    };
    template//哎呀,这里的语法不好
    struct wsprintf//一个或多个参数的专门化。
    {
    //胡说八道。。。
    };
    
    template <typename...>
    struct wsprintf;
    
    template <>
    struct wsprintf<> // specialization for no arguments
    {
        // blah blah ... 
    };
    
    template< class T, class... Args> // oops, bad syntax here was
    struct wsprintf<T, Args...> // specialization for one or more args.
    {
        // blah blah ... 
    };