C C 程式設計 名字查詢

2021-10-22 10:22:42 字數 2323 閱讀 8282

名字查詢,是當程式**現乙個名字時,將其與引入它的宣告聯絡起來的過程

例如,為編譯 std::cout << std::endl;,編譯器進行了:

對於函式和函式模板中的名字,名字查詢可以將同乙個名字和多個宣告聯絡起來,而且可能從實參依賴查詢中得到額外的宣告。還會進行模板實參推導,並將宣告的集合交給過載決議,由它選擇所要使用的那個宣告。成員訪問的規則只會在名字查詢和過載解析之後才被考慮,如果適用的話

出現在作用域解析操作符 :: 右邊的名字是限定名(參閱有限定的識別符號)。 限定名可能代表的是:

如果::左邊為空,則查詢過程僅會考慮全域性命名空間作用域中作出(或通過 using 宣告引入到全域性命名空間中)的宣告。這使得即使被區域性宣告隱藏的名字也能夠被訪問:

#include

intmain()

; std::cout <<

"fail\n"

;// 錯誤:對 'std' 的無限定查詢找到 struct

::std::cout <<

"ok\n"

;// 正確: ::std 找到命名空間 std

}

只有完成對 :: 左邊的名字的查詢(除非左邊所用的是 decltype 表示式或左邊為空),才能對其右邊的名字進行名字查詢。

struct a 

;int

main()

有限定的識別符號

有限定的標識表示式是在無限定的標識表示式前面帶上作用域解析運算子 ::,以及可選地帶上一系列以作用域解析運算子分隔的 列舉、 (c++11 起)類或命名空間的名字,或者 decltype 表示式 (c++11 起)

基本準則:受限名稱的名稱查詢是乙個受限作用域內部進行的,該受限作用域由乙個限定的構造所決定。如果該作用域是乙個類,那麼查詢範圍可以到達它的基類:但不會考慮它的我外圍作用域

int x;

classb;

classd:

public b

;void

f(d *pd)

基本準則:非受限名稱的查詢和受限名稱相反,它(由內到外)在所有外圍類中一層層進行查詢(但在某個類內部定義的成員函式定義中,它會先查詢該類和基類的作用域,然後才查詢外圍類的作用於)。這種查詢方式也叫做普通查詢

extern

int count ;

// 1

intlookup_example

(int count)

return count +

::count;

/ 第乙個非受限的count引用2,第2個受限的引用1

}

無限定的名稱查詢還可以依賴於引數的查詢(adl)

為什麼要引入adl?

我們來看個例子:

template

<

typename t>

inline t const

&max

(t const

&a, t const

&b)

假如我們現在要讓」在另乙個名字空間中定義的型別「使用這個模板引數:

namespace bigmath

;bool

operator

<

(bignumer const

&, bignumer const&)

;};using bigmath::bignumer;

void

g(bignumer const

&a, bignumer const

&b)

結果:

原因:max()模板並不知道bigmath名字空間,因此普通查詢也找不到應用於bignumber型別值的operator<。如果沒有特殊規則的話,這種限制會大大減少c++名字空間中的應用。adl正式基於這個特殊規則,也是解決這種限制的關鍵之處

C 名字查詢

在學習c 一開始,我們就知道在使用型別 變數和函式時需要先定義。名字查詢的過程比較直截了當 當然,對於定義在類內的成員函式中的名字與上述的查詢規則有所區別,類的定義分兩步處理 首先,編譯成員的宣告 直到類全部可見後,才編譯函式體。成員函式中使用的名字按照如下方式解析 例如下面 include usi...

c 的名字查詢

在c 中,函式編譯時檢查過程如下 第一步,執行名字查詢 name lookup 在呼叫類中查詢,並生成候選列表 若候選列表為空,再擴大查詢範圍 如名 字空間內,或父類 如此迴圈。如果最終無結果,那麼抱歉,就會提示你 名字未能找到 否則,編譯器跳到第二步。第二步,執行過載辨別 overload res...

C C 呼叫約定和名字約定

呼叫約定 cdecl stdcall 與 fastcall 三者都是呼叫約定 calling convention 它決定以下內容 1 函式引數的壓棧順序,2 由呼叫者還是被呼叫者把引數彈出棧,3 以及產生函式修飾名的方法。1 cdecl是c和c 程式的預設呼叫方式。每乙個呼叫它的函式都包含清空堆疊...