我尝试使用可变参数模板编写一个简单的记录器,以便我理解。它有效,但有一个问题。
void log() {
std::cout << std::endl;
}
// variadic Template
template<class T, class... Args>
void log(T t1, Args... args) {
std::cout << t1<<" ";
log(args...);
}
int main()
{
log("Logging", 1, 2, 3.2, 4);
return 0;
}
这不是在控制台中输出最后一个参数'4'
。输出为
Logging 1 2 3.2
当我调试时,它没有输入“空”&#39;记录功能。事实上,它编译并提供相同的输出而没有空log()
函数。
有人可以解释为什么这样做吗?
答案 0 :(得分:4)
在Visual Studio中,最好使用与std函数名称相似的命名空间
在log(4)
的全局命名空间调用中,评估为_GENERIC_MATH1(log, _CRTDEFAULT)
中定义的宏xtgmath.h
#include <iostream> // - this indirectly includes macro _GENERIC_MATH1 from ^^^^^^^
namespace mylog{
void log() {}
// variadic Template
template<class T, class... Args>
void log(T t1, Args... args)
{
std::cout << t1 << " ";
log(args...); // calling log with parameter pack
// but the last call is log(4)
// which is calling macro _GENERIC_MATH1 in global namespace
}
}
int main()
{
mylog::log("Logging", 1, 2, 3.2, 4);
return 0;
}
有关其他信息,请查看Some programmer dude答案。
答案 1 :(得分:3)
问题在于Visual C ++将std::log
引入全局命名空间。
您的电话串应
log("Logging", 1, 2, 3.2, 4);
log(1, 2, 3.2, 4);
log(2, 3.2, 4);
log(3.2, 4);
log(4);
log();
Visual C ++的问题在于,倒数第二个调用log(4)
实际上是std::log(4)
,当然不会调用您自己的log
函数。
最简单的解决方案是将您的功能重命名为其他内容。