簡體   English   中英

實例化和名稱綁定點

[英]point of instantiation and 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;
}

我雖然f是一個從屬名稱,1是g <int>的實例化點,2是g <double>的實例化點,所以對於g(1.1),f(double)是可見的,但是輸出是

int
int

如果我在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);
     ^

任何人都可以為我清除實例化和名稱綁定的概念嗎?

f(t)是依賴的非限定函數調用表達式,因此只有在定義上下文中找到的函數和通過ADL找到的函數才是候選函數。 f(int)在定義上下文中是可見的,但不是f(double) ,因此對於兩個調用,重載決策都解析為f(int)

ADL無法找到f(double) ,因為內置類型沒有關聯的類或名稱空間。 如果傳入類類型的參數,並且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)
}

調用f(A)是因為它位於全局命名空間中,並且A的關聯命名空間集是全局命名空間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM