A. c++primer3中,有一句話:「在多個文件之間編譯相同的函數模板定義增加了不必要的編譯時間」……
簡單點說,對於一個vector<int>的函數,比如size(),如果在不同的cpp中出現,在這些文件編譯的時候都要把vector<int>::size()編譯一遍。然後在鏈接的時候把重復的函數去掉。很顯然增加了編譯時間。
補充里你的理解是錯的,模板的聲明是不編譯的,更沒有空間,它根本不是實際的類型或函數,編譯器根本不管它。只有實例化的時候,才生成真正的類型、函數,而實例化的地方不在一起,必然造成同一個類型、函數被編譯了多次。反觀類的編譯,只在它的cpp中編譯一次,其他地方都使用它的頭文件得到聲明。
B. 如何製作「以編譯HTML文件」,這種形式的東東呀
使用QuickCHM軟體輕松編譯CHM格式的文件
談起CHM格式的文件,可能無人不曉,因為幾乎所有的軟體,現在都用CHM格式的文檔製作軟體幫助文件。另外,有很大一部分電子圖書也是用CHM格式編譯的。其實,編譯CHM格式的文件很簡單,下面就為大家介紹一款製作CHM文件的利器——QuickCHM。
軟體名稱:QuickCHM
軟體大小:1460KB
下載地址:http://www.skycn.com/soft/6785.html
在介紹QuickCHM之前,有必要對CHM的格式作個簡單說明。CHM文件格式是微軟1998年推出的基於HTML的幫助文件系統,它代替了早先的WinHelp幫助系統,能在Windows 98或NT及以上版本的操作系統中直接運行。
編譯CHM
QuickCHM未注冊時,只能編輯最多20個節點的項目,在製作CHM文件前,最好把要編譯進CHM中的文件編輯成HTML網頁文件,CHM格式的文件支持所有的網頁元素,所以你可以隨心所欲地在Dreamweaver等網頁編輯軟體中編輯HTML文件。QuickCHM自帶一個簡易的網頁編輯器,利用它可以編輯一些簡單的網頁,一般的做法是在Dreamweaver中做好網頁,然後在QuickCHM中進行局部的修改。
需要注意的是編譯進CHM文檔中的文件最好都放在同一個文件夾中。
啟動QuickCHM,在菜單欄執行「文件→新建」命令,新建一個「hhp」項目。切換到「目錄」頁,在菜單欄執行「主題→導入→添加文件夾」,導入待編譯的文件夾中的文件,注意,在彈出的「添加文件夾」對話框中,可以使用過濾器,防止圖片等某些類型的文件進入目錄。在默認的情況下,進入目錄中的各節點即主題都是以網頁標題顯示的(如圖1),也可以在「系統選項」中設置為以文件名顯示。接下來的任務,就是編輯目錄和網頁,下面就以這兩個方面作簡單的介紹。
編輯目錄:
目錄的編輯主要是重命名主題,修改主題圖標,排序主題,嵌套主題,新建主題和刪除主題,這些都可以利用右鍵快捷菜單和「目錄」頁上的按鈕完成。
編輯網頁:
QuickCHM集成了一個所見即所得的網頁編輯器,利用QuickCHM提供的網頁編輯工具箱(如圖1),可以完成大部分的網頁操作。切換到「源文件」頁,可以對HTML源代碼進行直接修改。和多數網頁編輯軟體一樣,切換到「預覽」頁,可以對當前網頁實時預覽。
圖1
利用同樣的方法,還可以給幫助系統做一個「索引」頁。
目錄和網頁編輯完成以後,就可以輸出CHM文檔了,不過在輸出前也可以把它保存為一個「.hhp」項目,以便日後繼續編輯。點擊工具欄上的「編譯」按鈕,編譯完成,如圖2所示,這是利用上述的方法製作的「瑞星殺毒軟體2004版」的幫助系統,從圖中可以看出,這個幫助系統的「面板」上只有「目錄」頁,沒有「索引」頁。
圖2
事實上,CHM文件的這個閱讀平台即「瀏覽窗體」的所有部分都可以在「編譯」前進行修改和定製,若你做進CHM幫助系統的各網頁間都能相互導航,我們甚至可以隱藏或關閉整個「面板」。
在菜單欄上執行「選項→項目選項」命令,彈出「參數」對話框,如圖3所示,在這里可以設定「主頁」、「默認頁」,顯示或隱藏工具欄按鈕和標題,顯示或隱藏面板及面板上的目錄、索引等,在這里還可以設定目錄的表現方式和整個窗體的外觀,添加「閃屏」(啟動時一個一閃而過的圖片,相當於軟體的啟動畫面)等,當然了,以上的所有設置必須在「編譯」前設置才能看到效果。
圖3
反編譯CHM
QuickCHM不僅能把HTML網頁、文本文件、圖片等編譯為一個CHM文件, 而且還能反編譯一個CHM文件,也就是說,利用QuickCHM,可以釋放CHM文件中的HTML文件、文本文件、圖片文件等資源,並且它能夠恢復源文件的全部目錄結構和文件名,以便幫助我們得到源文件進行資料恢復或二次編輯。
啟動QuickCHM,在菜單欄執行「文件→反編譯」,在彈出的對話框中選擇要進行反編譯的CHM文件以及反編譯得到的HTML文件和圖片等其它文件資源的保存位置,點擊「確定」,反編譯即可完成,同時保存HTML文件和圖片等其它文件的文件夾被打開。
C. 如何編譯SublimeText3主題文件
新建一個文件,保存為html格式,輸入html按一下tab鍵就可以了 這是系統內置的模板,還可以自定義,輸入一個關鍵詞,按一下tab鍵,就能自動完成。很方便
D. ctex編譯論文模板出錯,報錯如下:
我發現將.tex的文件,也就是你要編譯的文件放入 \ctex\MiKTeX\miktex\bin\ 是可以編譯的,我今天也這折騰了好久,因為一直都編譯不了,我還找過在線編譯,但是在線的特別爛,還一直都說我的模板是錯的,。。。無語,結果編譯後可以出pdf,放心吧,這方法我才實踐過~~注意這個比如是在你安裝了完整的CTeX前提下哦!其他好像還有別的方法我只是試過沒什麼用
E. 別人寫的latex模板為啥無法編譯啊
那要看具體情況. 有如下的幾種情況:
(1) 代碼有誤;
(2) 你計算機裡面的 Mitex 或 texlive 沒有所需的宏包;
(3) 編譯的方法不對;
(4) 編譯的源文件的文件類型不同,如utf8 和 GBK
總之,你這樣問問題還是很難解決的,要把具體錯誤的信息和代碼貼出來,才可能解決.
F. 為什麼C++編譯器不能支持對模板的分離式編譯
當編譯器將一個工程里的所有.cpp文件以分離的方式編譯完畢後,再由連接器(linker)進行連接成為一個.exe文件。 舉個例子: //---------------test.h-------------------//void f();//這里聲明一個函數f //---------------test.cpp--------------//#include」test.h」void f(){…//do something} //這里實現出test.h中聲明的f函數 //---------------main.cpp--------------//#include」test.h」int main(){f(); //調用f,f具有外部連接類型} 在這個例子中,test. cpp和main.cpp各自被編譯成不同的.obj文件(姑且命名為test.obj和main.obj),在main.cpp中,調用了f函數,然而當編譯器編譯main.cpp時,它所僅僅知道的只是main.cpp中所包含的test.h文件中的一個關於void f();的聲明,所以,編譯器將這里的f看作外部連接類型,即認為它的函數實現代碼在另一個.obj文件中,本例也就是test.obj,也就是說,main.obj中實際沒有關於f函數的哪怕一行二進制代碼,而這些代碼實際存在於test.cpp所編譯成的test.obj中。在main.obj中對f的調用只會生成一行call指令,像這樣: call f [C++中這個名字當然是經過mangling[處理]過的] 在編譯時,這個call指令顯然是錯誤的,因為main.obj中並無一行f的實現代碼。那怎麼辦呢?這就是連接器的任務,連接器負責在其它的.obj中(本例為test.obj)尋找f的實現代碼,找到以後將call f這個指令的調用地址換成實際的f的函數進入點地址。需要注意的是:連接器實際上將工程里的.obj「連接」成了一個.exe文件,而它最關鍵的任務就是上面說的,尋找一個外部連接符號在另一個.obj中的地址,然後替換原來的「虛假」地址。 這個過程如果說的更深入就是: call f這行指令其實並不是這樣的,它實際上是所謂的stub,也就是一個jmp 0xABCDEF。這個地址可能是任意的,然而關鍵是這個地址上有一行指令來進行真正的call f動作。也就是說,這個.obj文件裡面所有對f的調用都jmp向同一個地址,在後者那兒才真正」call」f。這樣做的好處就是連接器修改地址時只要對後者的call XXX地址作改動就行了。但是,連接器是如何找到f的實際地址的呢(在本例中這處於test.obj中),因為.obj與.exe的格式是一樣的,在這樣的文件中有一個符號導入表和符號導出表(import table和export table)其中將所有符號和它們的地址關聯起來。這樣連接器只要在test.obj的符號導出表中尋找符號f(當然C++對f作了mangling)的地址就行了,然後作一些偏移量處理後(因為是將兩個.obj文件合並,當然地址會有一定的偏移,這個連接器清楚)寫入main.obj中的符號導入表中f所佔有的那一項即可。 這就是大概的過程。其中關鍵就是: 編譯main.cpp時,編譯器不知道f的實現,所以當碰到對它的調用時只是給出一個指示,指示連接器應該為它尋找f的實現體。這也就是說main.obj中沒有關於f的任何一行二進制代碼。 編譯test.cpp時,編譯器找到了f的實現。於是乎f的實現(二進制代碼)出現在test.obj里。 連接時,連接器在test.obj中找到f的實現代碼(二進制)的地址(通過符號導出表)。然後將main.obj中懸而未決的call XXX地址改成f實際的地址。完成。 然而,對於模板,你知道,模板函數的代碼其實並不能直接編譯成二進制代碼,其中要有一個「實例化」的過程。舉個例子: //----------main.cpp------//template<class T>void f(T t){} int main(){…//do somethingf(10); // call f<int> 編譯器在這里決定給f一個f<int>的實例…//do other thing} 也就是說,如果你在main.cpp文件中沒有調用過f,f也就得不到實例化,從而main.obj中也就沒有關於f的任意一行二進制代碼!如果你這樣調用了: f(10); // f<int>得以實例化出來f(10.0); // f<double>得以實例化出來 這樣main.obj中也就有了f<int>,f<double>兩個函數的二進制代碼段。以此類推。 然而實例化要求編譯器知道模板的定義,不是嗎? 看下面的例子(將模板的聲明和實現分離): //-------------test.h----------------//template<class T>class A{public:void f(); // 這里只是個聲明}; //---------------test.cpp-------------//#include」test.h」template<class T>void A<T>::f() // 模板的實現{ …//do something} //---------------main.cpp---------------//#include」test.h」int main(){A<int> a;f(); // #1} 編譯器在#1處並不知道A<int>::f的定義,因為它不在test.h裡面,於是編譯器只好寄希望於連接器,希望它能夠在其他.obj裡面找到A<int>::f的實例,在本例中就是test.obj,然而,後者中真有A<int>::f的二進制代碼嗎?NO!!!因為C++標准明確表示,當一個模板不被用到的時侯它就不該被實例化出來,test.cpp中用到了A<int>::f了嗎?沒有!!
G. STM32為什麼我按照模板添加了文件還是編譯不成功
你可以在頭文件中定義 數據類型 struct student{} 和 函數
然後主函數中調用加上#include <myproject.h> 在這個頭文件里的實現函數 要是正確的能夠通過編譯的
其實也可建議你寫一個dll
或則你直接把數據類型 struct student{} 變數為全局變數 各個函數都可以調用 挺好的
H. C++中模板的編譯與文件部署問題
模板這玩意不在當前編譯單元(也就是cpp)里使用就不會被編譯(想編譯也編譯不了,起碼不完整) 所以一般要麼寫在和調用同一個cpp里,要麼完全寫在.h里(不是把聲明寫.h里把定義寫在.cpp里,直接把定義寫在.h里)
模板不會產生定義重復問題。 (指鏈接的時候... 你怎麼搞出重復定義的我還真想不出來...)
第三個問題沒看明白bbb
--
#include的功能...就是把一個文件的內容直接粘貼到當前文件...
比如是
a.cpp
1
#include "b.h"
2
b.h
3
與處理後就會有a.i
1
#line 1 "b.h"
3
#line 3 "a.cpp"
2
這種結果,只是把b.h的內容插入了#include "b.h"的位置。那兩個#line不用管,是為了正確返回錯誤出現位置用的。
--
模板必須有定義因為必須在使用的時候補完。你不使用根本沒辦法編譯模板。
比如你在a.cpp里寫了一個模板,b.cpp里使用這個模板。a.cpp里並沒有使用模板所以根本沒有編譯(模板只有使用的時候才能提供編譯需要的參數)。b.cpp里使用的話,根本鏈接不到相應的代碼。
I. 用Latex編譯國外期刊模板時, 顯示enter the file, entering extended mode
應該是缺少宏包, 具體看日誌.
編輯引擎現在一般都使用的是 LaTeX 格式, TeX 格式的文檔很少使用了.
除了 pdfLaTeX , 再試一試 XeLaTeX.
J. 請問一下c++多文件模板編譯 a.cpp 和a.h 生成liba.so 在usea 中調用 a.cpp 裡面有定義模板 謝謝
目前基本沒有 C++ 編譯器支持template分離編譯吧
模板函數實現放到頭文件里