Linux gcc picking试图在函数所在的位置实例化一个模板

Linux gcc picking trying to instantiate a template where function should be

本文关键字:一个 实例化 picking gcc 函数 Linux 位置      更新时间:2023-10-16

我有以下重现错误的示例代码:

// non-namespacing this compiles as expected
namespace n
{
    template <typename T>
    void foo(T const & t)
    {
        t.doesnt_have_this_method();
    }
}
template <typename T>
void bar(T const & t)
{
    // picks the template over the overload
    n::foo(t);
}
namespace n
{
    // function overload
    void foo(int const &);
}
void n::foo(int const &) {}

int main()
{
    int a;
    bar(a);
}

该代码在MSVC 2010和Solaris 8编译器上都能很好地编译。但是gcc4(GCC)4.1.2 20071124(Red Hat 4.1.2-42)失败,错误为:

test.cpp: In function 'void n::foo(const T&) [with T = int]':
test.cpp:14:   instantiated from 'void bar(const T&) [with T = int]'
test.cpp:34:   instantiated from here
test.cpp:6: error: 'const int' has no member named 'doesnt_have_this_method'

模板bar似乎没有看到foo函数过载。我想弄清楚为什么会发生这种事。我知道有三件事可以缓解这个问题,但在生产环境中很难执行:

  1. 在CCD_ 4之前声明CCD_。这是我可以在我的prod代码中做的事情,但将来很难在整个代码库中强制执行
  2. 不将CCD_ 5放在命名空间中。这是我不能做的事情,因为我正在与另一个图书馆对接
  3. 使得过载成为模板专用化CCD_ 6。有些事情我不能做,因为foo(int const &)的声明超出了我的控制

请帮我了解如何解决这个问题。为什么编译器没有选择正确的函数?

bar的定义中,唯一可见的foo是函数模板,因为另一个尚未声明。

相关文章: