考虑以下 C++ 代码示例:
namespace n
{
struct A {};
}
struct B {};
void foo(int) {}
template<typename T>
void quux()
{
foo(T());
}
void foo(n::A) {}
void foo(B) {}
int main()
{
quux<n::A>(); // Error (but works if you comment out the foo(int) declaration)
quux<B>(); // Works
return 0;
}
如注释中所示,模板实例化quux<n::A>()
会导致编译器错误(在 GCC 4.6.3 上):
foo.cpp: In function ‘void quux() [with T = n::A]’:
foo.cpp:22:16: instantiated from here
foo.cpp:13:5: error: cannot convert ‘n::A’ to ‘int’ for argument ‘1’ to ‘void foo(int)’
有人可以向我解释发生了什么吗?我本来希望它与quux<B>()
. 它必须与何时foo
被视为依赖有关。不幸的是,我的 C++ foo 还不够好。当foo(int)
声明不存在时,该示例编译得很好,这也让我感到惊讶。
欢迎任何提示、解释和解决方法。
更新1:
我不想(读不能)foo(n::A)
在定义之前移动声明quux
(这将避免错误)。
更新 2:
感谢 David 指出相关问题Template function call 被在 template 之前声明的签名错误的函数混淆。Johannes Schaub 接受的答案 - litb 提出了一个包装类解决方案,在我的情况下也可以作为一种解决方法。但是,我对它并不是 100% 满意。
更新 3:
我通过将 in 的定义foo(n::A)
放入 namespace解决了这个问题n
。感谢 Jesse Good 和 bames53 的有用回答,他们不仅指出了标准的相关部分,还提供了替代解决方案。感谢 David Rodríguez - dribeas 在我没有正确理解所提出的解决方案时的解释以及所有其他贡献者。