简体   繁体   English

实例化和名称绑定点

[英]point of instantiation and name binding

I am confused about the point of instantiation with the following example: 我对以下示例的实例化问题感到困惑:

#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;
}

I though f is a dependent name and 1. is the point of instantiation for g< int > and 2. is the point of instantiation for g< double >, so f(double) is visible for g(1.1), however the output is 我虽然f是一个从属名称,1是g <int>的实例化点,2是g <double>的实例化点,所以对于g(1.1),f(double)是可见的,但是输出是

int
int

and if I comment the declaration of f(int) at 3, gcc reports an error (not surprise) and points out f(t) at 4 is the point of instantiation(surprised!!). 如果我在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);
     ^

Can anyone clear the concept of point of instantiation and name binding for me please? 任何人都可以为我清除实例化和名称绑定的概念吗?

f(t) is a dependent unqualified function call expression, so only functions found within the definition context and those found via ADL are candidates. f(t)是依赖的非限定函数调用表达式,因此只有在定义上下文中找到的函数和通过ADL找到的函数才是候选函数。 f(int) is visible within the definition context, but not f(double) , so overload resolution resolves to f(int) for both calls. f(int)在定义上下文中是可见的,但不是f(double) ,因此对于两个调用,重载决策都解析为f(int)

f(double) cannot be found by ADL because built-in types have no associated classes or namespaces. ADL无法找到f(double) ,因为内置类型没有关联的类或名称空间。 If you passed in an argument of class type, and there was an overload of f taking this type, ADL will be able to find it. 如果传入类类型的参数,并且f类型的重载采用此类型,则ADL将能够找到它。 For example: 例如:

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)
}

f(A) is called because it is located in the global namespace, and A 's associated namespace set is the global namespace. 调用f(A)是因为它位于全局命名空间中,并且A的关联命名空间集是全局命名空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM