template<typename T>class A{public: voID f(T,T){};};namespace ns{ typedef int TT; voID f(int,int){};};template<typename T>class B : public A<T>{public: voID g() { //f(T(),T()); // it's fine for error here typedef ns::TT TTT; f(TTT(),T()); // why this issued an error? f(ns::TT(),T()); // and this? }};/* I also think it's OK to move ns here */// namespace ns// {// typedef int TT;// voID f(int,int){};//};int main(){ B<int> b; b.g();}
请注意第二条评论.由于“f”是从属名称,因此应将其查找延迟到“main”函数中的实例化.此时,编译器应在main函数的范围内执行与参数相关的名称查找.我想现在它应该在命名空间ns中发现函数,但它仍然发出了编译错误:
1.cpp: In instantiation of 'voID B<T>::g() [with T = int]':1.cpp:30:6: required from here1.cpp:23:15: error: 'f' was not declared in this scope,and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] f(TTT(),T()); //why this issued an error? ^1.cpp:23:15: note: declarations in dependent base 'A<int>' are not found by unqualifIEd lookup1.cpp:23:15: note: use 'this->f' instead
有人可以向我解释一下吗?谢谢.
解决方法 依赖于参数的查找仅搜索参数类型的关联类和名称空间. typedef只是一个透明的别名,类似于using声明.从标准n3485草案,[basic.lookup.argdep] / 2关于依赖于参数的查找:
For each argument type
T
in the function call,there is a set of zero or more associated namespaces and a set of zero or more associated classes to be consIDered. The sets of namespaces and classes is determined entirely by the types of the function arguments (and the namespace of any template template argument). Typedef names and using-declarations used to specify the types do not contribute to this set.
[强调我的]
template<typename T>class A{public: voID f(T,int){};};template<typename T>class B : public A<T> // note the base class is dependent{public: voID g() { //f(T(),T()); // and this? }};
由于基类是相关的,因此在非限定查找期间不会搜索它.因此,可以使用参数依赖查找找到f.您正确地声明f将仅在“第二阶段”(在实例化时)搜索,如在您的调用中,至少一个参数依赖于模板参数.
但是,ns不是依赖名称,也不是TT(在ns :: TT中).因此,名称空间和TT必须在它们用于g的定义之前声明.
无论是编写f(ns :: TT(),T())还是f(T(),T())都不会影响在参数依赖查找期间搜索f的一般规则:只有关联的命名空间和类参数的类型(T和ns :: TT).两者都是B< int> :: g()的整数,因此没有关联的类和名称空间.
f(TTT(),TTT())改变查找,因为现在f是在名字查找阶段查找(它不是从属名称).
以下是依赖于参数的查找示例:
namespace ns{ struct TT {}; voID f(TT,TT) {}}int main(){ ns::TT x; f(x,x);}
现在,您也可以在类模板的成员函数中执行此 *** 作:
namespace ns{ struct TT {}; voID f(TT,TT) {}}template<typename T>struct B{ voID g() { f(T(),T()); }};int main(){ B<ns::TT> x; x.g();}
但是,正如我所说,依赖于参数的名称查找不适用于诸如int之类的基本类型.
在上面的示例中,f再次依赖,因为至少一个参数依赖于模板参数.因此,您也可以写:
template<typename T>struct B{ voID g() { f(T(),T()); // looked up during the second phase,// from the point of instantiation }};namespace ns{ struct TT {}; voID f(TT,TT) {}}int main(){ B<ns::TT> x; x.g();}总结
以上是内存溢出为你收集整理的c – 在模板中执行参数依赖名称查找时的奇怪行为全部内容,希望文章能够帮你解决c – 在模板中执行参数依赖名称查找时的奇怪行为所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)