在C ++中选择函数重载时的GCC意外行为

时间:2016-02-10 10:48:09

标签: c++ visual-c++ gcc overloading

考虑以下示例:

#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()中选择此函数。

为什么会有不同的行为,具体取决于声明函数的顺序或它们是否在全局命名空间中?

要考虑的事情让我感到困惑:

  • 为什么片段#3的工作方式与我预期的一样,而片段#2则没有?唯一的区别是函数都是相同的,但是它们自己的命名空间而不是全局命名空间。
  • 在回复@juanchopanza的评论时,如果在调用nr::tostr(nr::logging::Level)时函数重载nr::log()不存在,为什么片段#3会按照我的预期执行?顺序仍然相同(在nr::log()之后声明函数重载)

标有*的代码段无法正常工作

0 个答案:

没有答案