模板解析在<;在C++;对象模型>; 在“C++内部对象模型”的第7章中,作者写道,名字的解析取决于名称的使用是否与“实例化模板的参数类型”有关。 我写了一个测试: /// -------------Test.h--------------- #ifndef TEST_H #define TEST_H #include <iostream> using namespace std; extern double foo(double t); template <typename T> class Test { public: void fun1() { member = foo(val); } T fun2() { return foo(member); } private: int val; T member; }; #endif //--------------Test.h--------------- #ifndef试验 #定义测试 #包括 使用名称空间std; 外部双foo(双t); 模板 课堂测试{ 公众: void fun1(){ 成员=foo(val); } T fun2(){ 返回foo(成员); } 私人: int-val; T成员; }; #恩迪夫

模板解析在<;在C++;对象模型>; 在“C++内部对象模型”的第7章中,作者写道,名字的解析取决于名称的使用是否与“实例化模板的参数类型”有关。 我写了一个测试: /// -------------Test.h--------------- #ifndef TEST_H #define TEST_H #include <iostream> using namespace std; extern double foo(double t); template <typename T> class Test { public: void fun1() { member = foo(val); } T fun2() { return foo(member); } private: int val; T member; }; #endif //--------------Test.h--------------- #ifndef试验 #定义测试 #包括 使用名称空间std; 外部双foo(双t); 模板 课堂测试{ 公众: void fun1(){ 成员=foo(val); } T fun2(){ 返回foo(成员); } 私人: int-val; T成员; }; #恩迪夫,c++,templates,resolution,C++,Templates,Resolution,及 //--------------test1.cc------------- #包括 使用名称空间std; 双福(双t){ Couth我怕这本书不是画完整的图片(而且它有点老了)。是的, fo(成员)< /> >是一个依赖于模板参数的函数调用。但是在模板中查找函数的具体方式在C++标准中描述为: 对于后缀表达式为从属名称的函数调用, 候选函数是使用常用的查找规则找到的 ([basic.lookup.unqual],[basic.lookup.argdep]),除了: 对于使用非限定名称查找的

//--------------test1.cc-------------
#包括
使用名称空间std;
双福(双t){

Couth

我怕这本书不是画完整的图片(而且它有点老了)。是的,<代码> fo(成员)< /> >是一个依赖于模板参数的函数调用。但是在模板中查找函数的具体方式在C++标准中描述为:

对于后缀表达式为从属名称的函数调用, 候选函数是使用常用的查找规则找到的 ([basic.lookup.unqual],[basic.lookup.argdep]),除了:

  • 对于使用非限定名称查找的查找部分,只找到模板定义上下文中的函数声明
  • 对于使用关联名称空间([basic.lookup.argdep])的查找部分,在 模板定义上下文或模板实例化上下文 找到了
foo
的重载可以通过两种方式之一进行查找。通过直接非限定查找和(也称为ADL)。简单非限定查找只考虑在模板定义点已知的名称。因为您只声明了
foo(double)
,这是在模板定义点找到的唯一重载

在实例化时,编译器将尝试进行ADL以查找更多的
foo
,但基本类型对ADL没有贡献。
int
不能用于查找
foo(int)
。因此编译器只能做一件事,将整数转换为双精度,并调用
foo(double)

如果要测试编译器ADL,只需添加一个简单的用户定义类型和重载。例如:

enum E{};
E foo(E) {
  cout << "foo E is called\n";
  return {};
}

int main() {
    Test<E> fi;
    fi.fun1();
    fi.fun2(); 
    return 0;
}
enum E{};
易福(E){
库特
enum E{};
E foo(E) {
  cout << "foo E is called\n";
  return {};
}

int main() {
    Test<E> fi;
    fi.fun1();
    fi.fun2(); 
    return 0;
}