如何用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”?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)