ene*_*ski 7 c++ variadic-templates c++11
在我的代码中,我使用可变参数模板函数进行日志记录.但是当我std::endl用作参数时,我得到以下编译器错误:
错误:没有匹配函数来调用'LOG_ERROR(const char [14],int&,)'LOG_ERROR("sum of x + y =",z,std :: endl);
注意:候选人:'void LOG_ERROR()'内联void LOG_ERROR(){
注意:候选人需要0个参数,3个提供
我的代码:
#include <iostream>
inline void LOG_ERROR() {
std::cout << std::endl;
}
template<typename First, typename ...Rest>
void LOG_ERROR(First && first, Rest && ...rest){
std::cout << std::forward<First>(first);
LOG_ERROR(std::forward<Rest>(rest)...);
}
int main() {
int foo=40;
LOG_ERROR("My foo = ", foo, std::endl);
}
Run Code Online (Sandbox Code Playgroud)
代码工作得很好,"\n"但我很想知道它为什么失败std::endl以及如何解决它
长话短说 - std::endl是函数模板,模板参数在传递时无法推断.您可以这样帮助您的编译器:
LOG_ERROR("My foo = ", foo, std::endl<char, std::char_traits<char>>);
Run Code Online (Sandbox Code Playgroud)
尽管我觉得这是一段丑陋的代码,但它完美无缺.
在有人提供更好的解决方案之前,您可以使用具有适当运算符重载的简单包装器:
struct EndlWrap {};
std::ostream& operator << (std::ostream& os, EndlWrap) {
return os << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
应该像这样使用:
LOG_ERROR("My foo = ", foo, EndlWrap{});
Run Code Online (Sandbox Code Playgroud)
当您的日志记录目标可能是非标准流时,这有一个优势,即,std::endl当它<<进入流时,仍然可以推导出模板参数.