如何实现“可变参数模板”与预c++0x(VS2008)?
我正在使用 Visual Studio 2008,并且我想实现没有变量参数列表的字符串格式化功能。
如何使用 pre-c++0x(VS2008) 实现“Variadic Template”?
有没有像boost这样实现这个的库?
或者另一种方式来实现这个?
这是我的示例代码。 (当然,这是不能遵守的,因为我使用的是VS2008。)
bool VarPrint(std::ostringstream& out, const std::string& s)
{
std::string::size_type offset = 0;
if((offset = s.find("%")) != std::string::npos)
{
if(!(offset != s.size() - 1 && s[offset + 1] == '%'))
{
ASSERT(!"Missing Arguments!");
return false;
}
}
out << s;
return true;
}
template<typename T, typename... Args>
bool VarPrint(std::ostringstream& out, const std::string& s, const T& value, const Args&... args)
{
std::string::size_type prev_offset = 0;
std::string::size_type curr_offset = 0;
while((curr_offset = s.find("%", prev_offset)) != std::string::npos)
{
out << s.substr(prev_offset, curr_offset);
if(!(curr_offset != s.size() - 1 && s[curr_offset + 1] == '%'))
{
out << value;
if(curr_offset + 2 < s.length())
return VarPrint(out, s.substr(curr_offset + 2), args...); return true;
}
prev_offset = curr_offset + 2;
if(prev_offset >= s.length)
break;
}
ASSERT(!"Extra Argument Provided!");
return false;
}
I'm using Visual Studio 2008, and I want to implement string formatting function without Variable Argument List.
How to implement "Variadic Template" with pre-c++0x(VS2008)?
Is there any library which implements this like boost?
Or another way to implement this?
Here is my sample code.
(of course, this can't be complied because i'm using VS2008.)
bool VarPrint(std::ostringstream& out, const std::string& s)
{
std::string::size_type offset = 0;
if((offset = s.find("%")) != std::string::npos)
{
if(!(offset != s.size() - 1 && s[offset + 1] == '%'))
{
ASSERT(!"Missing Arguments!");
return false;
}
}
out << s;
return true;
}
template<typename T, typename... Args>
bool VarPrint(std::ostringstream& out, const std::string& s, const T& value, const Args&... args)
{
std::string::size_type prev_offset = 0;
std::string::size_type curr_offset = 0;
while((curr_offset = s.find("%", prev_offset)) != std::string::npos)
{
out << s.substr(prev_offset, curr_offset);
if(!(curr_offset != s.size() - 1 && s[curr_offset + 1] == '%'))
{
out << value;
if(curr_offset + 2 < s.length())
return VarPrint(out, s.substr(curr_offset + 2), args...); return true;
}
prev_offset = curr_offset + 2;
if(prev_offset >= s.length)
break;
}
ASSERT(!"Extra Argument Provided!");
return false;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 C++03 中,您有不同的可能性:
cons(1)("some string")(foo)
)operator()
或operator%
如 Boost.Format)我觉得第一个选项有点棘手,因为不是每个人都可以轻松理解宏,所以我会如果您计划很快迁移到 C++0x,则仅将其保留用于短期解决方案。
第三个选项可能提供良好的自定义功能(在许多语言中,格式化是通过
%
符号完成的),但这也意味着人们需要记住这个特定的“可变参数”函数每次是如何工作的。我个人更喜欢 cons 方法,因为它解决了这两个问题:
例如,以下是它的工作原理:
本示例将使用的包含:
结果类型的助手附加一个值(前置可能会更有效,但这意味着以相反的顺序传递参数,这是违反直觉的):
Cons
模板本身,带有一个神奇的operator()
附加值。请注意,它创建了一个具有不同类型的新项目:使用它重新访问的
VarPrint
:演示:
输出:
In C++03, you have different possibilities:
cons(1)("some string")(foo)
)operator()
for example, oroperator%
like Boost.Format)The first option is a bit tricky, I feel, because not everyone can understand macros easily, so I would only reserve it for short-terms solutions if you plan on migrating to C++0x soon.
The third option may provide a nice custom touch (formatting is done with a
%
sign in many languages), but it also means that one needs to remember how this particular "variadic" function works each time.My personal preference is the
cons
approach because it solves both issues:For example, here is how it could work:
The includes that this example will use:
A helper for the result type of appending a value (it could be more efficient with prepending, but that would mean passing the arguments in reverse order which is counter-intuitive):
The
Cons
template itself, with a magicoperator()
to append value. Note that it creates a new item with a different type:A revisited
VarPrint
with it:And the demo:
Output:
C++03 中没有可变参数模板功能。 Boost 和其他设计良好的库以不同的方式解决这个问题。对于函数,可以有多个 N + 1 重载,其中每个重载采用 0 到 N 个参数。对于类,可以有一个包含最多 N 个参数的定义,这些参数默认为某种无效类型。这个更高的限制通常可以通过一些宏进行配置;因为将其设置为高会增加编译时间的开销,而将其设置为低将导致用户无法传递足够的参数。
对于您的特定情况,我将以递归方式实现
VarPrint
。递归中的每一步都将处理一个参数,并使用修改后的格式字符串发出递归调用,并将所有左值左移一个位置。There is no variadic template functionality in C++03. Boost and other well designed libraries work around this in different ways. For functions, one can have a number of N + 1 overloads where each overload take from 0 to N arguments. For classes, one can have a single definition with up to N arguments that default to some invalid type. This higher limits are usually configurable via some macro; because setting it to high will impose an overhead in compile times, and setting it to low will cause users not being able to pass enough arguments.
For your particular case, I would implement
VarPrint
in a recursive way. Each step up in the recursion will process a single argument, and issue a recursive call with a modified format string and all the left values shifted left one position.