【发布时间】:2019-08-31 15:51:32
【问题描述】:
我正在尝试使用 /permissive- 在 VS2019 中编译一些代码,其中涉及模板和重载,并且正在发生奇怪的事情。 (https://godbolt.org/z/fBbQu6)
就像在上帝螺栓中一样,当我的 templateFunc() 在两个重载之间声明时,如下所示:
namespace Foospace {
class A;
void func(A*) {};
template<class T> void templateFunc() { Foospace::func((T*)0); }
class B;
void func(B*) {};
void func() { Foospace::templateFunc<B>(); }
}
我收到error C2664: 'void Foospace::func(Foospace::A *)': cannot convert argument 1 from 'T *' to 'Foospace::A *'
如果我将 templateFunc() 移到重载之下,它显然可以工作:
namespace Foospace {
class A;
void func(A*) {};
class B;
void func(B*) {};
template<class T> void templateFunc() { Foospace::func((T*)0); }
void func() { Foospace::templateFunc<B>(); }
}
如果我在两个同样有效的重载之前移动 templateFunc():
namespace Foospace {
template<class T> void templateFunc() { Foospace::func((T*)0); }
class A;
void func(A*) {};
class B;
void func(B*) {};
void func() { Foospace::templateFunc<B>(); }
}
如果我将 templateFunc() 保留在两个重载之间,但只是从对 func() 的调用中删除了 Foospace 命名空间限定符,那么突然之间这也可以了:
namespace Foospace {
class A;
void func(A*) {};
template<class T> void templateFunc() { func((T*)0); }
class B;
void func(B*) {};
void func() { Foospace::templateFunc<B>(); }
}
这是怎么回事?
【问题讨论】:
-
这看起来像一个编译器错误。第三种情况应该失败。规则很晦涩,但您可以从查找 ADL 和两阶段查找开始。
-
@T.C.等等,不,我很困惑。我记得在某个地方看到只有 ADL 在实例化时应用,限定名称不应该禁用它吗?
-
Nvm,我数不过来。
标签: c++ visual-studio templates