考虑以下示例:
#include <string>
#include <iostream>
namespace nr {
template <typename T>
static inline std::string tostr(T const& v)
{
return std::to_string(v);
}
}
namespace nr {
namespace logging {
enum Level {
kDebug,
kInfo,
kWarning,
kError
};
template <typename T>
static inline void log(std::string const& message, T const& v)
{
std::cout << message << nr::tostr(v) << "\n";
}
}
}
namespace nr {
static inline std::string tostr(nr::logging::Level level)
{
switch (level) {
case nr::logging::kDebug:
return "DEBUG";
case nr::logging::kInfo:
return "INFO";
case nr::logging::kWarning:
return "WARNING";
case nr::logging::kError:
return "ERROR";
default:
return "UNKNOWN_LEVEL";
}
}
}
int main()
{
nr::logging::log("Hello", nr::logging::kInfo);
nr::logging::log("Hello", nr::logging::kWarning);
}
这是在Ubuntu 15.10上使用GCC 5.2.1编译的输出
Hello1
Hello2
我希望它能够输出,并且它在Windows上使用MSVC 2013:
HelloINFO
HelloWARNING
我找到了修复它的方法,但我不明白为什么会有不同的行为!据我所知,nr::logging::log()
模板是在第一次调用函数时实例化的。在这一点上,nr::tostr(nr::logging::Level)
已经定义,因此它应该在nr::logging::log()
中选择此函数。
为什么会有不同的行为,具体取决于声明函数的顺序或它们是否在全局命名空间中?
要考虑的事情让我感到困惑:
nr::tostr(nr::logging::Level)
时函数重载nr::log()
不存在,为什么片段#3会按照我的预期执行?顺序仍然相同(在nr::log()
之后声明函数重载)nr
namespace * nr::tostr(nr::logging::Level)
before nr::logging::log()
标有*的代码段无法正常工作