[英]Templates :Name resolution:Dependent template arguments : -->can any one tell some more examples for this statement?
[英]Templates :Name resolution:Point of instantiation: -->can any one tell some more examples for this statement?
這是ISO C ++標准14.6.4.1實例化的聲明
對於函數模板特化,成員函數模板特化,或成員函數或類模板的靜態數據成員的特化,如果特化是隱式實例化的,因為它是從另一個模板特化和其中的上下文中引用的引用依賴於模板參數,專門化的實例化點是封閉專門化的實例化點。 否則,這種特化的實例化點緊跟在引用特化的命名空間范圍聲明或定義之后。
如果以使用該函數模板或成員函數的默認參數的定義的方式調用類模板的函數模板或成員函數,則默認參數的實例化點是函數模板的實例化點或成員職能專業化。
對於類模板特化,類成員模板特化或類模板的類成員的特化,如果特化是隱式實例化的,因為它是從另一個模板特化中引用的,如果引用特化的上下文取決於在模板參數上,如果是
在封閉模板的實例化之前不實例化特化,實例化的點緊接在封閉模板的實例化之前。 否則,重點
這種特化的實例化緊接在命名空間范圍聲明或引用特化的定義之前。
我無法為整個部分編寫程序。 我試圖從昨天開始編寫本節目的程序。
任何人都可以為我提供一些代碼供您理解。
請,通常..我試着問一個或多個積分。 在任何部分。 但是這里我無法理解本節中的一點。
所以,任何人都可以為我提供一個代碼(程序)供本部分理解。
我覺得這很令人頭疼,委員會也有這么多的樂趣 。 所以我認為我可能在下面有一些錯誤。 所以請仔細閱讀:)
第三段
對於類模板特化,類成員模板特化或類模板的類成員的特化,如果特化是隱式實例化的,因為它是從另一個模板特化中引用的,如果引用特化的上下文取決於在模板參數上,並且如果在封閉模板的實例化之前未實例化特化,則實例化的點緊接在封閉模板的實例化之前。
換句話說,如果實例化類模板或類模板的嵌套類,並且導致該實例化的上下文依賴於模板參數,則模板/嵌套類在實例化模板的實例化之前立即實例化它。
在其它專門的上下文可以依賴於模板的參數,這是主模板,偏特和類模板的成員的情況下,或它不依賴於模板的參數,其是用於從明確的特化中的引用的情況。
否則[即上下文是非依賴的],這種特化的實例化點緊接在引用特化的命名空間范圍聲明或定義之前。
這種區別很重要。 考慮如果從依賴上下文的特化實例化將立即在命名空間范圍聲明或引用它的定義之前會發生什么
template<typename T, int N>
struct A {
typedef typename A<T, N-1>::type *type;
};
template<typename T>
struct A<T, 0> {
typedef T type;
};
typedef A<int, 2>::type ptr;
該模板應該添加N
指針聲明符。 所以A<int, 2>
例如是int**
。
typedef A<int, 2>::type
周圍的上下文是非依賴的,因此在typedef聲明之前實例化A<int, 2>
。 在 A<int, 2>
,我們有A<int, N-1>::type
,它出現在一個依賴的上下文中,它引用了A<int, 1>::type
。 所以標准要求我們在實例化A<int, 1>
的同一點實例化A<int, 2>
。
如果我們將緊接該提交給它(主模板定義之前)的命名空間范圍聲明之前實例化這一點,我們不會注意到的部分特A<T, 0>
處理時`A<int, N-1>::type
在A<int, 1>
因為我們將在該特化之前實例化A<int, 1>
。
第二段
這樣,在默認參數中查找的名稱與在其所用函數的其余部分中查找的名稱一致(即,它們的POI與其函數模板的POI /類模板的成員函數相同)。
第一段
這基本上與第三段相同。 但是,函數模板在引用它們的實體之后被實例化,以便可以進行遞歸使用,如下例所示。 相反,類模板在引用它們的實體之前被實例化,因為實體要求類類型完整。 如果類類型的POI將在該實體之后,則類類型仍然不存在。
template<typename T>
void f(T);
template<typename T>
struct A {
void g() {
f(0);
}
void h() { /* do a dance */ }
};
template<typename T>
void f(T t) {
A<T> a;
a.h();
}
void g() {
A<int> a;
a.g();
}
如果f
將在 A<int>
之前實例化,那么它無法訪問ah()
因為此時它還不存在。 因此,函數模板在引用它們的實體之后被實例化,並且類模板在引用它們的實體之前被實例化。
要求一些人糾正我的理解......
我認為下面的代碼說明了1和2的含義(根據我的理解):
template<class T> void f1(T t){cout << 0;} template<class T> void f2(T t, void (*p)(int) = f1){ (*p)(0); } void f(double d){cout << 1;} template<class T> void g(T t){ f1(t); // this is the interesting call. } void f1(int t){cout << 2;} int main(){ g(2); f2(2); } // POI for f1(t), Also POI for f2(2)
考慮調用g(2)。
在POI,基本上有三個可見的重載(可行):
然而,該調用將路由到'f(int)',因為這是最佳匹配。
以同樣的方式,'f2(2)'的POI是主要的右大括號。
從該POI再次查詢默認參數'f1'並解析為'f1(int)',這是所有三個可用重載的最佳匹配。
謝謝@litb。 在@litb修改我的理解后修改:
template<class A> struct T{
T(int x = 0){}
};
template<class A> struct U{
U():t(f(A())){}
T<A> t;
}; // POI of 'gt' instantiation
T<int> gt(f(2)); // At this point 'f' is not found, hence error
int f(int x){return x;}
int main(){
U<int> u;
} // There are 2 POIs here 'U<int>::T<int>' and 'U<int>' and in that order
// Therefore 'f' is visible from here.
請記住,在上述兩個調用中,有兩個重載是候選。 namspace函數'f1(double)'和友元函數'f1'聲明(由於ADL而找到)。 由於這是唯一可行的函數,因此調用將解析為朋友聲明'f1'。
我認為第3點意味着:
template<class A> struct T{ T(int x = 0){} }; template<class A> struct U{ U():t(f(A())){} T<A> t; }; // POI of 'gt' instantiation T<int> gt(f(2)); // At this point 'f' is not found, hence error int f(int x){return x;} int main(){ U<int> u; } // There are 2 POIs here 'U<int>::T<int>' and 'U<int>' and in that order // Therefore 'f' is visible from here.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.