Sha*_*ian 4 c++ instantiation name-binding
我对以下示例的实例化问题感到困惑:
#include <iostream>
void f(int){std::cout<<"int"<<std::endl;}//3
template <typename T>
void g(T t)
{
f(t);//4
}
void f(double){std::cout<<"double"<<std::endl;}
int main()
{
g<int>(1);//1.point of instantiation for g<int>
g<double>(1.1);//2.point of instantiation for g<double>, so f(double) is visible from here?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我虽然f是一个从属名称,1是g <int>的实例化点,2是g <double>的实例化点,所以对于g(1.1),f(double)是可见的,但是输出是
int
int
Run Code Online (Sandbox Code Playgroud)
如果我在3处评论f(int)的声明,gcc报告错误(不是惊讶),并指出f(t)在4是实例化点(惊讶!!).
test.cpp: In instantiation of ‘void g(T) [with T = int]’:
test.cpp:16:10: required from here
test.cpp:9:5: error: ‘f’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
f(t);
^
Run Code Online (Sandbox Code Playgroud)
任何人都可以为我清除实例化和名称绑定的概念吗?
f(t)是一个依赖的非限定函数调用表达式,因此只有在定义上下文中找到的函数和通过ADL找到的函数才是候选函数.f(int)在定义上下文中是可见的,但不是f(double),因此重载决议解析f(int)为两个调用.
f(double)ADL无法找到,因为内置类型没有关联的类或命名空间.如果传入类类型的参数,并且存在重载f此类型,ADL将能够找到它.例如:
void f(int);
template <typename T>
void g(T t)
{
f(t);
}
class A {};
void f(double);
void f(A);
int main()
{
g(1); // calls f(int)
g(1.1); // calls f(int)
g(A{}); // calls f(A)
}
Run Code Online (Sandbox Code Playgroud)
f(A)因为它位于全局名称空间中而被调用,并且A相关联的名称空间集是全局名称空间.