variadic template

turing-complete 2014-01-11 09:18:35
下面的代码有没有更简单的方法实现相同的功能:支持若干个输入参数,获取一个md5值。
现在的问题是,为了实现这个功能,要写三个函数,感觉有点多。
另,我不想用这个帖子上的解决方案。

inline void InternalMD5Update(MD5_CTX* ctx, const std::string& data) {
MD5_Update(ctx, data.data(), data.size());
}

template<typename... TArgsPack>
void InternalMD5Update(MD5_CTX* ctx, const std::string& data, const TArgsPack&... args) {
InternalMD5Update(ctx, data);
InternalMD5Update(ctx, args...);
}

template<typename... TArgsPack>
std::string GetMd5(const TArgsPack&... args) {
MD5_CTX ctx;
unsigned char md5[16];
MD5_Init(&ctx);

InternalMD5Update(&ctx, args...);

MD5_Final(md5, &ctx);

return std::string(md5, sizeof(md5));
}
...全文
212 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
taodm 2014-01-12
  • 打赏
  • 举报
回复
for (const std::string* data : {&args...}) {
turing-complete 2014-01-12
  • 打赏
  • 举报
回复
经过大家的提议,这是目前总结出来的一个较好的替换方案,函数个数从3个减为1。 但,还是有些差强人意,这里面有循环,而且std::initializer_list<std::string>可能还有复制。
template<typename... TArgsPack>                                                                                                                                                                
std::string GetMd5(const TArgsPack&... args) {                                                 
  MD5_CTX ctx;                                                                                 
  unsigned char md5[16];                                                                       
  MD5_Init(&ctx);                                                                              
                                                                                               
  for (const std::string& data : {args...}) {                                                  
    MD5_Update(&ctx, data.data(), data.size());                                                
  }                                                                                            
                                                                                               
  MD5_Final(md5, &ctx);                                                                        
                                                                                               
  return ConvertBytesToHexString(md5, sizeof(md5));                                            
}
ri_aje 2014-01-12
  • 打赏
  • 举报
回复
引用 9 楼 mougaidong 的回复:
经过大家的提议,这是目前总结出来的一个较好的替换方案,函数个数从3个减为1。 但,还是有些差强人意,这里面有循环,而且std::initializer_list<std::string>可能还有复制。
template<typename... TArgsPack>                                                                                                                                                                
std::string GetMd5(const TArgsPack&... args) {                                                 
  MD5_CTX ctx;                                                                                 
  unsigned char md5[16];                                                                       
  MD5_Init(&ctx);                                                                              
                                                                                               
  for (const std::string& data : {args...}) {                                                  
    MD5_Update(&ctx, data.data(), data.size());                                                
  }                                                                                            
                                                                                               
  MD5_Final(md5, &ctx);                                                                        
                                                                                               
  return ConvertBytesToHexString(md5, sizeof(md5));                                            
}
怕复制开销,可以改成这样。

    auto const f = [&](std::string const &s)
    {
        MD5_Update(&ctx,s.data(),s.size());
        return true;
    };
    for (auto const& _ : {f(ts)...}) { (void)_; } 
其实主楼是最简单的方法了,要想再写的简单漂亮只能依赖库的支持了,可惜 c++11 没有 static_for_each。 后面给的循环或者 list initialization 的方法无法保证编译期展开;而使用变参函数模板又不能保证求值顺序,都是以词骇意的感觉。
vipcxj 2014-01-11
  • 打赏
  • 举报
回复
引用 7 楼 taodm 的回复:
还没折腾结束啊 vector<string *> + initializer_list + parameter pack expansion



template<typename... TArgsPack>
std::string GetMd5(const TArgsPack&&... args) {
  std::array<std::string, sizeof...(args)> arr = {std::forward<TArgsPack>(args)...};
  MD5_CTX ctx;
  unsigned char md5[16];
  MD5_Init(&ctx);

  for (std::string& data : arr)
  {
     MD5_Update(ctx, data, data.size());
  }
 
  MD5_Final(md5, &ctx);
 
  return std::string(md5, sizeof(md5));
}

谢谢LS提醒~
taodm 2014-01-11
  • 打赏
  • 举报
回复
还没折腾结束啊 vector<string *> + initializer_list + parameter pack expansion
vipcxj 2014-01-11
  • 打赏
  • 举报
回复
引用 5 楼 mougaidong 的回复:
从性能上讲,这个方案有较大损耗。不能成为一个合格的替代方案。 [quote=引用 4 楼 vipcxj 的回复:]


template<typename... TArgsPack>
std::string GetMd5(const TArgsPack&&... args) {
  auto inargs(std::make_tuple(std::forward<TArgsPack>(args)...);
  MD5_CTX ctx;
  unsigned char md5[16];
  MD5_Init(&ctx);
  argnum = sizeof...(inargs);
  for (int i = 0; i < argnum; ++i)
  {
     const int id = i;
     std::string data = std::get<id>(inargs);
     MD5_Update(ctx, data, data.size());
  }
 
  MD5_Final(md5, &ctx);
 
  return std::string(md5, sizeof(md5));
}
这个?
[/quote] 貌似这代码没法编译通过,所以已经不是性能的问题了,我刚刚又找了好多方法,貌似没找到使用递归模板外的遍历元组的方法~
turing-complete 2014-01-11
  • 打赏
  • 举报
回复
从性能上讲,这个方案有较大损耗。不能成为一个合格的替代方案。
引用 4 楼 vipcxj 的回复:


template<typename... TArgsPack>
std::string GetMd5(const TArgsPack&&... args) {
  auto inargs(std::make_tuple(std::forward<TArgsPack>(args)...);
  MD5_CTX ctx;
  unsigned char md5[16];
  MD5_Init(&ctx);
  argnum = sizeof...(inargs);
  for (int i = 0; i < argnum; ++i)
  {
     const int id = i;
     std::string data = std::get<id>(inargs);
     MD5_Update(ctx, data, data.size());
  }
 
  MD5_Final(md5, &ctx);
 
  return std::string(md5, sizeof(md5));
}
这个?
vipcxj 2014-01-11
  • 打赏
  • 举报
回复


template<typename... TArgsPack>
std::string GetMd5(const TArgsPack&&... args) {
  auto inargs(std::make_tuple(std::forward<TArgsPack>(args)...);
  MD5_CTX ctx;
  unsigned char md5[16];
  MD5_Init(&ctx);
  argnum = sizeof...(inargs);
  for (int i = 0; i < argnum; ++i)
  {
     const int id = i;
     std::string data = std::get<id>(inargs);
     MD5_Update(ctx, data, data.size());
  }
 
  MD5_Final(md5, &ctx);
 
  return std::string(md5, sizeof(md5));
}
这个?
taodm 2014-01-11
  • 打赏
  • 举报
回复
那就看你啥时候反应过来了。
turing-complete 2014-01-11
  • 打赏
  • 举报
回复
如果这样可以,我就用std::initializer_list了。我不想给调用者增加任何使用负担。
引用 1 楼 taodm 的回复:
有必要那么复杂么,vector<strig>就搞定了。
taodm 2014-01-11
  • 打赏
  • 举报
回复
有必要那么复杂么,vector<strig>就搞定了。
《C++ Template》第二版,2017年9月16日出版 Templates are among the most powerful features of C++, but they remain misunderstood and underutilized, even as the C++ language and development community have advanced. In C++ Templates, Second Editi on, three pioneering C++ experts show why, when, and how to use modern templates to build software that’s cleaner, faster, more efficient, and easier to maintain. Now extensively updated for the C++11, C++14, and C++17 standards, this new edition presents state-of-the-art techniques for a wider spectrum of applications. The authors provide authoritative explanations of all new language features that either improve templates or interact with them, including variadic templates, generic lambdas, class template argument deduction, compile-time if, forwarding references, and user-defined literals. They also deeply delve into fundamental language concepts (like value categories) and fully cover all standard type traits. The book starts with an insightful tutorial on basic concepts and relevant language features. The remainder of the book serves as a comprehensive reference, focusing first on language details and then on coding techniques, advanced applications, and sophisticated idioms. Throughout, examples clearly illustrate abstract concepts and demonstrate best practices for exploiting all that C++ templates can do. Understand exactly how templates behave, and avoid common pitfalls Use templates to write more efficient, flexible, and maintainable software Master today’s most effective idioms and techniques Reuse source code without compromising performance or safety Benefit from utilities for generic programming in the C++ Standard Library Preview the upcoming concepts feature The companion website, tmplbook.com, contains sample code and additional updates.
《C++ Template》第二版,2017年9月16日出版 Templates are among the most powerful features of C++, but they remain misunderstood and underutilized, even as the C++ language and development community have advanced. In C++ Templates, Second Editi on, three pioneering C++ experts show why, when, and how to use modern templates to build software that’s cleaner, faster, more efficient, and easier to maintain. Now extensively updated for the C++11, C++14, and C++17 standards, this new edition presents state-of-the-art techniques for a wider spectrum of applications. The authors provide authoritative explanations of all new language features that either improve templates or interact with them, including variadic templates, generic lambdas, class template argument deduction, compile-time if, forwarding references, and user-defined literals. They also deeply delve into fundamental language concepts (like value categories) and fully cover all standard type traits. The book starts with an insightful tutorial on basic concepts and relevant language features. The remainder of the book serves as a comprehensive reference, focusing first on language details and then on coding techniques, advanced applications, and sophisticated idioms. Throughout, examples clearly illustrate abstract concepts and demonstrate best practices for exploiting all that C++ templates can do. Understand exactly how templates behave, and avoid common pitfalls Use templates to write more efficient, flexible, and maintainable software Master today’s most effective idioms and techniques Reuse source code without compromising performance or safety Benefit from utilities for generic programming in the C++ Standard Library Preview the upcoming concepts feature The companion website, tmplbook.com, contains sample code and additional updates.

64,633

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧