C++ 递归可变模板函数部分模板专门化的替代方法
我正在使用递归变量模板编写sprintf()的替代方案,如中所述。我的目标是允许为用户定义的类型轻松添加自定义数据类型格式化程序。例如,如果基本实现如下所示: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
#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 ...
};