久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

GCC 和 MS 編譯器的模板實例化細節

Template instantiation details of GCC and MS compilers(GCC 和 MS 編譯器的模板實例化細節)
本文介紹了GCC 和 MS 編譯器的模板實例化細節的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

限時送ChatGPT賬號..

誰能提供模板實例化的比較或具體細節在 GCC 和 MS 編譯器的編譯和/或鏈接時處理?這個過程不一樣嗎在靜態庫、共享庫和可執行文件的上下文中?我找到了 this doc 關于 GCC 如何處理它,但我不確定如果信息仍然是指事物的現狀.我應該使用標志嗎他們在編譯我的庫時建議在那里,例如-fno-implicit-templates?

我所知道的(可能不一定正確)是:

  • 模板會在實際使用時實例化
  • 模板將作為顯式實例化的結果進行實例化
  • 重復實例化通常通過折疊重復實例化或將實例化推遲到鏈接時間來處理

解決方案


實例化點

<塊引用>

模板會在實際使用時實例化

不完全是,但大致上.實例化的精確點有點微妙,我將您委托給名為 實例化點,在 Vandevoorde/Josuttis 的好書中.

然而,編譯器不一定正確實現 POI:Bug c++/41995:函數模板的實例化點不正確

<小時>

部分實例化

<塊引用>

模板會在實際使用時實例化

那是部分正確的.對于函數模板來說是這樣,但是對于類模板,只有使用到的成員函數才會被實例化.以下是格式良好的代碼:

#include 模板結構 Foo {void let_me_stay() {這個->是->有效->代碼.下車->下車->我的->草坪;}void fun() { std::cout <<有趣()"<<std::endl;}};int主(){Foo富;foo.fun();}

let_me_stay() 在語法上被檢查(并且那里的語法是正確的),但在語義上沒有被檢查(即它不被解釋).


兩階段查找

然而,只有依賴代碼被稍后解釋;顯然,在 Foo<> 中,this 依賴于實例化 Foo<> 所使用的確切模板 ID,因此我們推遲了Foo<>::let_me_alone() 的錯誤檢查,直到實例化時間.

但是如果我們不使用依賴于具體實例化的東西,代碼一定是好的.因此,以下內容格式良好:

$ cat non-dependent.cc模板結構 Foo {void I_wont_compile() { 我的-> 是-> 有效-> 代碼.下車->下車->我的->草坪;}};int main () {}//注意:沒有單個實例化

Mine 對編譯器來說是一個完全未知的符號,與 this 不同,編譯器可以確定它的實例依賴關系.

這里的關鍵點是 C++ 使用了 兩階段查找,它在第一階段檢查非依賴代碼,依賴代碼的語義檢查是在第二階段(和實例化時間)完成的(這也是一個經常被誤解或未知的概念,許多 C++ 程序員認為模板在實例化之前根本不會被解析,但這只是神話來自......., 微軟 C++).


類模板的完整實例化

Foo<>::let_me_stay() 的定義有效,因為錯誤檢查被推遲到以后,至于 this 指針,它是依賴的.除非你會使用

<塊引用>

顯式實例化

cat >foo.cc#include 模板結構 Foo {void let_me_stay() { this->is->valid->code.下車->下車->我的->草坪;}void fun() { std::cout <<有趣()"<<std::endl;}};模板結構 Foo;int主(){Foo富;foo.fun();}g++ foo.cc錯誤:錯誤:struct Foo"沒有名為is"的成員


不同翻譯單位的模板定義

當您顯式實例化時,就是顯式實例化.并使所有符號對鏈接器可見,這也意味著模板定義可能駐留在不同的翻譯單元中:

$ cat A.cc模板結構 Foo {無效的樂趣();//注意:沒有定義};int主(){Foo().fun();}$貓 B.cc#include 模板結構 Foo {無效的樂趣();};模板 void Foo::fun() {std::cout <<樂趣!"<<std::endl;}//注意:帶有外部鏈接的定義模板結構 Foo;//在 void 上顯式實例化$ g++ A.cc B.cc$ ./a.out樂趣!

但是,您必須顯式實例化所有要使用的模板參數,否則

$ cat A.cc模板結構 Foo {無效的樂趣();//注意:沒有定義};int主(){Foo<float>().fun();}$ g++ A.cc B.cc對 `Foo::fun()' 的未定義引用

<小時>

關于兩階段查找的小說明:編譯器是否真正實現了兩階段查找并不是由標準規定的.然而,為了符合要求,它應該像它一樣工作(就像加法或乘法不一定必須使用加法或乘法 CPU 指令來執行一樣.

Could anyone provide a comparison or specific details of how is template instantiation handled at compile and/or link time in GCC and MS compilers? Is this process different in the context of static libraries, shared libraries and executables? I found this doc about how GCC handles it but I'm not sure if the information is still referring to the current state of things. Should I use the flags they suggest there when compiling my libraries e.g. -fno-implicit-templates?

What I know (might not necessarily be correct) is that:

  • templates will be instantiated when actually used
  • templates will be instantiated as a result of explicit instantiations
  • duplicate instantiation is usually handled by folding duplicate instantiations, or by deferring instantiation until link time

解決方案


Point of instantiation

templates will be instantiated when actually used

Not exactly, but roughly. The precise point of instantiation is a bit subtle, and I delegate you over to the section named Point of instantiation in Vandevoorde's/Josuttis' fine book.

However, compilers do not necessarily implement the POIs correctly: Bug c++/41995: Incorrect point of instantiation for function template


Partial instantiation

templates will be instantiated when actually used

That is partially correct. It is true for function templates, but for class templates, only the member functions that are used are instantiated. The following is well-formed code:

#include <iostream>

template <typename> struct Foo {
    void let_me_stay() {
        this->is->valid->code. get->off->my->lawn;
    }

    void fun() { std::cout << "fun()" << std::endl; } 
};


int main () {
    Foo<void> foo;
    foo.fun();
}

let_me_stay() is checked syntactically (and the syntax there is correct), but not semantically (i.e. it is not interpreted).


Two phase lookup

However, only dependent code is interpreted later; clearly, within Foo<>, this is dependent upon the exact template-id with which Foo<> is instantiated, so we postponed error-checking of Foo<>::let_me_alone() until instantiation time.

But if we do not use something that depends on the specific instantiation, the code must be good. Therefore, the following is not well-formed:

$ cat non-dependent.cc
template <typename> struct Foo {
    void I_wont_compile() { Mine->is->valid->code. get->off->my->lawn; }
};
int main () {} // note: no single instantiation

Mine is a completely unknown symbol to the compiler, unlike this, for which the compiler could determine it's instance dependency.

The key-point here is that C++ uses a model of two-phase-lookup, where it does checking for non-dependent code in the first phase, and semantic checking for dependent code is done in phase two (and instantiation time) (this is also an often misunderstood or unknown concept, many C++ programmers assume that templates are not parsed at all until instantiation, but that's only myth coming from, ..., Microsoft C++).


Full instantiation of class templates

The definition of Foo<>::let_me_stay() worked because error checking was postponed to later, as for the this pointer, which is dependent. Except when you would have made use of

explicit instantiations

cat > foo.cc
#include <iostream>

template <typename> struct Foo {
    void let_me_stay() { this->is->valid->code. get->off->my->lawn; }
    void fun() { std::cout << "fun()" << std::endl; } 
};

template struct Foo<void>;
int main () {
    Foo<void> foo;
    foo.fun();
}

g++ foo.cc
error: error: ‘struct Foo<void>’ has no member named ‘is’


Template definitions in different units of translation

When you explicitly instantiate, you instantiate explicitly. And make all symbols visible to the linker, which also means that the template definition may reside in different units of translation:

$ cat A.cc
template <typename> struct Foo {
    void fun();  // Note: no definition
};
int main () {
    Foo<void>().fun();
}

$ cat B.cc
#include <iostream>
template <typename> struct Foo {
    void fun();

};
template <typename T>
void Foo<T>::fun() { 
    std::cout << "fun!" << std::endl;
}  // Note: definition with extern linkage

template struct Foo<void>; // explicit instantiation upon void

$ g++ A.cc B.cc
$ ./a.out
fun!

However, you must explicitly instantiate for all template arguments to be used, otherwise

$ cat A.cc
template <typename> struct Foo {
    void fun();  // Note: no definition
};
int main () {
    Foo<float>().fun();
}
$ g++ A.cc B.cc
undefined reference to `Foo<float>::fun()'


Small note about two-phase lookup: Whether a compiler actually implements two-phase lookup is not dictated by the standard. To be conformant, however, it should work as if it did (just like addition or multiplication do not necessarily have to be performed using addition or multiplication CPU instructions.

這篇關于GCC 和 MS 編譯器的模板實例化細節的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

Difference between std::reference_wrapper and simple pointer?(std::reference_wrapper 和簡單指針的區別?)
Difference between const. pointer and reference?(常量之間的區別.指針和引用?)
How to access the contents of a vector from a pointer to the vector in C++?(c++ - 如何從指向向量的指針訪問向量的內容?)
Meaning of *amp; and **amp; in C++(*amp; 的含義和**amp;在 C++ 中)
Why can#39;t I do polymorphism with normal variables?(為什么我不能對普通變量進行多態?)
Dereferencing deleted pointers always result in an Access Violation?(取消引用已刪除的指針總是會導致訪問沖突?)
主站蜘蛛池模板: 黄色网址在线免费播放 | 国产99久久久久 | 鲁一鲁资源影视 | 亚洲精品成人免费 | 国产精品久久久久久久久久久久久 | 91视频在线观看 | 日本精品一区二区三区四区 | 伊人久久精品 | 国产一区二区三区免费 | 国产一区二区三区高清 | 福利视频网 | 在线免费观看日本视频 | 亚洲欧美另类在线 | 日韩电影免费在线观看中文字幕 | 久久综合伊人 | 国产福利91精品 | 精品一二三区视频 | 欧美啪啪网站 | japanhd成人 | 黄网在线观看 | 欧美视频中文字幕 | 亚洲最大看片网站 | 国产精品a级 | 一区免费看 | 欧美一区二区在线观看视频 | 日韩中文字幕一区 | 国产欧美精品一区二区 | 天天操天天舔 | 成年人在线观看 | 国产精品免费观看视频 | 蜜臀久久99精品久久久久久宅男 | 狠狠做六月爱婷婷综合aⅴ 国产精品视频网 | 免费精品久久久久久中文字幕 | 亚洲国产精品一区二区www | 欧美区日韩区 | 国产精品视频在 | 正在播放国产精品 | 日韩在线视频免费观看 | 天堂av中文| 国产成人网 | 国产精品一区二区久久精品爱微奶 |