Linux gcc picking 试图实例化一个模板,其中函数应该是
Linux gcc picking trying to instantiate a template where function should be
我有以下重现错误的示例代码:
// 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
函数重载。我想弄清楚为什么会这样。我知道的三件事可以缓解这个问题,但很难在生产环境中执行:
- 在
bar
之前声明 foo(int const &)
。这是我可以在我的产品代码中做的事情,但将来很难在整个代码库中强制执行
- 未将
foo
放入命名空间。这是我不能做的事情,因为我正在与另一个库交互。
- 使重载成为模板特化
template<> void n::foo(int const &)
。我不能做的事情,因为 foo(int const &)
的声明不在我的控制范围内。
请帮助我了解如何解决此问题。为什么编译器没有选择正确的函数?
在 bar
的定义中,唯一可见的 foo
是函数模板,因为另一个尚未声明。
我有以下重现错误的示例代码:
// 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
函数重载。我想弄清楚为什么会这样。我知道的三件事可以缓解这个问题,但很难在生产环境中执行:
- 在
bar
之前声明foo(int const &)
。这是我可以在我的产品代码中做的事情,但将来很难在整个代码库中强制执行 - 未将
foo
放入命名空间。这是我不能做的事情,因为我正在与另一个库交互。 - 使重载成为模板特化
template<> void n::foo(int const &)
。我不能做的事情,因为foo(int const &)
的声明不在我的控制范围内。
请帮助我了解如何解决此问题。为什么编译器没有选择正确的函数?
在 bar
的定义中,唯一可见的 foo
是函数模板,因为另一个尚未声明。