如何用pre-c 0x(VS2008)实现“Variadic Template”?

如何用pre-c 0x(VS2008)实现“Variadic Template”?,第1张

概述我使用的是Visual Studio 2008,我想实现没有变量参数列表的字符串格式化函数. 如何用pre-c 0x(VS2008)实现“Variadic Template”? 有没有任何图书馆实现这样的提升? 还是另一种方式来实现呢? 这是我的示例代码. (当然,由于我使用的是VS2008,所以无法遵守.) bool VarPrint(std::ostringstream& out, const 我使用的是Visual Studio 2008,我想实现没有变量参数列表的字符串格式化函数.

如何用pre-c 0x(VS2008)实现“Variadic Template”?

有没有任何图书馆实现这样的提升?

还是另一种方式来实现呢?

这是我的示例代码.
(当然,由于我使用的是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;}
@R_403_6120@ 在C 03,你有不同的可能性:

>为0-N参数生成重载(例如使用Boost.Preprocessor)
>使用Cons-Lists(cons(1)(“some string”)(foo))
>使用对象并重载一些运算符(operator()),或者像运算符%(如Boost.Format))

第一个选项是有点棘手,我觉得,因为并不是每个人都可以很容易的理解宏,所以我只会保留它的短期解决方案,如果你计划迁移到C 0x很快.

第三个选项可能会提供一个很好的自定义触摸(使用许多语言的%符号进行格式化),但这也意味着需要记住这个特定的“可变”功能如何每次都工作.

我的个人喜好是cons方法,因为它解决了这两个问题:

>定义只涉及模板,所以它比1更可读和维护.
您可以定义一次机器,然后可以将其重新用于任何“可变”功能(并且它们仍然是功能),因此它更加一致,并且可以节省您的工作

例如,这里是如何工作的:

这个例子包括:

#include <cassert>#include <iostream>#include <string>

对于附加值的结果类型的帮助器(它可能会更有效的前置,但这意味着以相反的顺序传递参数是反直觉的):

template <typename T,typename Next> struct Cons;struct ConsEmpty;template <typename Cons,typename U>struct cons_result;template <typename U>struct cons_result<ConsEmpty,U> {  typedef Cons<U,ConsEmpty> type;};template <typename T,typename U>struct cons_result<Cons<T,ConsEmpty>,U> {  typedef Cons<T,Cons<U,ConsEmpty> > type;};template <typename T,typename Next,Next>,typename cons_result<Next,U>::type> type;};

缺点模板本身,用一个魔术运算符()来附加值.请注意,它会创建一个不同类型的新项目:

template <typename T,typename Next>struct Cons {  Cons(T t,Next n): value(t),next(n) {}  T value;  Next next;  template <typename U>  typename cons_result<Cons,U>::type operator()(U u) {    typedef typename cons_result<Cons,U>::type Result;    return Result(value,next(u));  }};struct ConsEmpty {  template <typename U>  Cons<U,ConsEmpty> operator()(U u) {    return Cons<U,ConsEmpty>(u,ConsEmpty());  }};template <typename T>Cons<T,ConsEmpty> cons(T t) {  return Cons<T,ConsEmpty>(t,ConsEmpty());}

重读了VarPrint:

bool VarPrint(std::ostream& out,ConsEmpty) {    std::string::size_type offset = 0;    if((offset = s.find("%")) != std::string::npos) {        if(offset == s.size() - 1 || s[offset + 1] != '%')  {            assert(0 && "Missing Arguments!");            return false;        }    }    out << s;    return true;}template<typename T,typename Next>bool VarPrint(std::ostream& out,std::string const& s,Cons<T,Next> const& cons) {    std::string::size_type prev_offset = 0,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 << cons.value;            if(curr_offset + 2 < s.length())                return VarPrint(out,cons.next);            return true;        }        prev_offset = curr_offset + 2;        if(prev_offset >= s.length())            break;    }    assert(0 && "Extra Argument ProvIDed!");    return false;}

和演示

int main() {  VarPrint(std::cout,"integer %i\n",cons(1));  VarPrint(std::cout,"mix of %i and %s\n",cons(2)("foo"));}

您可以查看ideone的输出:

integer 1mix of 2 and foo
总结

以上是内存溢出为你收集整理的如何用pre-c 0x(VS2008)实现“Variadic Template”?全部内容,希望文章能够帮你解决如何用pre-c 0x(VS2008)实现“Variadic Template”?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1246152.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存