Nem*_*emo 2 c++ constants variadic-templates c++17
好吧所以
为了好玩而开发一个简单的日志系统,遇到了一个有趣的问题。我认为能够写一些类似以下内容的东西会很好:
Log(Info, "Result: {}", value);
给我一个像这样的结果
Result: 45
(此处使用 fmt 的格式样式。)
所以我这样设置函数:
template <typename ...args_t>
void Log(LogLevel Level, const char* Message, args_t&&... Args)
Run Code Online (Sandbox Code Playgroud)
效果很好,没有任何问题。但是,我的想法是,如果函数未修改参数,则应将其标记为 const (用于优化并作为给程序员的注释),所以我尝试了以下方法:
template <typename ...args_t>
void Log(const LogLevel Level, const char* Message, const args_t&&... Args)
Run Code Online (Sandbox Code Playgroud)
这一直给我错误,VS2017给了我
error C2665: 'Log': none of the 4 overloads could convert all the argument types
我只是做错了吗?我不应该担心参数包常量吗?有一个更好的方法吗?有时,这个参数打包业务很难让我理解。
(我花了大约 3 个小时研究这个问题,但在堆栈溢出或整个互联网上找不到任何相关信息,如果这个问题已经在其他地方得到了回答,请原谅我。)
当您真正想要的是 const 引用时,您正在使用转发引用。
args_t&&用。。。来代替const args_t&。
转发引用使用与右值引用相同的语法声明,并带有双精度值&(so &&)。两者的区别在于它是否出现在推导的上下文中:转发引用是推导的,而右值引用则不是。换句话说,如果编译器使用您的函数参数来确定模板参数是什么(例如您的情况),那么它就是转发引用。否则,它是一个右值引用。
在您的情况下,const最好使用引用,因为您明确不打算修改参数。由于您永远不想通过非const引用接受参数,因此不需要完美的转发,使用引用const将为您提供编译器检查的不变性以及接受纯右值(例如文字等)的能力。
| 归档时间: |
|
| 查看次数: |
776 次 |
| 最近记录: |