當前位置:首頁 » 編程軟體 » 模板編譯期替換

模板編譯期替換

發布時間: 2022-05-29 07:32:12

『壹』 Vue 模板編譯 是用來代替JSP的嗎

JSP可以和Vue一起使用,但vue本身更傾向於基於node的服務端渲染SSR

『貳』 c++primer3中,有一句話:「在多個文件之間編譯相同的函數模板定義增加了不必要的編譯時間」……

簡單點說,對於一個vector<int>的函數,比如size(),如果在不同的cpp中出現,在這些文件編譯的時候都要把vector<int>::size()編譯一遍。然後在鏈接的時候把重復的函數去掉。很顯然增加了編譯時間。

補充里你的理解是錯的,模板的聲明是不編譯的,更沒有空間,它根本不是實際的類型或函數,編譯器根本不管它。只有實例化的時候,才生成真正的類型、函數,而實例化的地方不在一起,必然造成同一個類型、函數被編譯了多次。反觀類的編譯,只在它的cpp中編譯一次,其他地方都使用它的頭文件得到聲明。

『叄』 c++函數模板替代函數編寫

一樓的很有意思,你這篇文章其實是很經典的,但與本問題無關...

問題在這一句:

string e = myfunc("aa", "bbb");

編譯器已經很明確地告訴你了,不能把2個指針相加,因為在用雙引號括起來的字元都是所謂的C風格字元串,即以一個指針來標明其首個字元並以'/0'作為結束信號的字元串,比如:

const char* p = "hello, world!";

如果你將其打出,如:

cout << p;

則指針p便會把其指向的字元逐個列印出來,再遇到'\0'時結束。

在你的問題中,由於"aa"和"bbb"無法被轉化為string類,所以編譯器不會調用這個函數:

string myfunc(string a, string b)
{
string c = a + b;
return c;
}

而是為它們生成了特定的模版:

char* myfunc(char* a, char* b);

由於兩個指針的相加是沒有被定義的,所以編譯器報錯。

由於string e = myfunc("aa", "bbb")中的"aa"和"bbb"被默認作為了C風格的字元串,而編譯器沒有定義一種隱式的轉換方法可以把C風格字元串轉化為string類,所以你必須通過顯式地把它們轉換為string類字元串,可以這樣:

string e = myfunc(string("aa"),string("bbb"));

或者用更加一目瞭然且安全但煩瑣而冗長的C++式cast句法:

string e = myfunc(static_cast<string>("aa"), static_cast<string>("bbb"));

另外說下用了模版的話你的這個函數就可以砍掉了:

string myfunc(string a, string b)
{
string c = a + b;
return c;
}

另外如果你不想煩瑣地每次調用myfunc來實現2個字元的相加都要通過cast的話也可以把myfunc模板實例化:

#include <iostream>
#include <string>
#include <cmath>
#include <cstring>
using namespace std;

template<class T>
T myfunc(T a,T b){
T c=a+b;
return c;
}
// 模板實例化
template<> const char* myfunc<const char*>(const char* a, const char* b)
{
string temp = string(a) + string(b);
return temp.c_str(); // 結果可能出乎你的預料~
}

// 或者

// 模板實例化
/* template<> const char* myfunc<const char*>(const char* a, const char* b)
{
char* pa = new char[sizeof a + sizeof b];
const char* pc = strcat(strcpy(pa, a), b);
delete [] pa;

return pc; // 同上
}*/

int main(){
int c;
float d;
c=myfunc(3,4);
cout<<c<<endl;
d=myfunc(3.4,4.7);
cout<<d<<endl;
string e=myfunc("aa","bbb");
cout<<e<<endl;
system("pause");
return 0;
}

你運行這個程序得到的e可能是亂碼,原因可見一樓的部分提示:

8. 不要再寫 char* p = "XXX" 這種語句,要寫成 const char* p = "XXX",編譯器之所以讓前者通過編譯是為了兼容以前的大量的舊代碼。
BTW:const TYPE* p 和 TYPE const* p 是一樣的,風格不同而已。
BTW:C語言中也有const關鍵字。

詳細可見:

http://community.csdn.net/Expert/TopicView3.asp?id=5085350

『肆』 請教C++模板函數在編譯時處理

模板函數類型檢查是放在調用的時候檢查的.因為在定義的時候是沒有辦法區分的(比如你這個例子,就存在int轉換float和float轉換int的警告級別差異.)

所以嚴格的說來,編譯器是發現調用了test(v1,u1),才開始檢查的.由於底層實現將形參類型用實際V1和u1的類型做了替換,然後就可以實際判斷隱式轉換的合理性.

『伍』 為什麼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了嗎?沒有!!

『陸』 C中預處理命令 #error 用法是怎麼樣的 請舉例.

比如說你的源代碼只能在Linux平台運行,那麼可以有
#ifdef WIN32
#error This programme cannot compile @ Windows Platform
#endif
這樣如果WIN32被定義過了,就不允許編譯

『柒』 請問 c++中 模板是 編譯時多態還是運行時多態,或者都不是,求解

是編譯時多態。所有的模板都是在編譯時產生對應的代碼,它沒有面向對象中的虛表,無法實現動態多態。

你仔細想一想,模板在應用時都必須指定確定的類型,而運行多態僅需指定一個基類就OK啦。

『捌』 PSD模板 怎麼替換裡面的圖片

工具:pscs6

1、打開ps的軟體進入,然後把需要編輯的ps打開進入,如圖所示,然後再右側選中需要更換圖片的圖層。

『玖』 template<class T>這種用法在C++中有嗎什麼意思怎麼用

可以
template < typename T >
T max( T a, T b )
{
return a < b ? b : a;
}
這個 max 函數就是一個模板函數,它可以傳入一個 「類型」的參數,以便實現任意類型求最大值的效果。假設我們這樣使用它:
int x=5, y=10;
int z=max <int>( x, y );
這時候發生了什麼呢?我們傳入的「類型參數」是int,因此編譯器在編譯這段代碼時會使用 int 來構造一個新函數:
int max( int a, int b )
{
return a < b ? b : a;
}
後面的事就和編譯普通的函數一樣了,C++編譯器繼續使用強類型系統編譯這個函數,由強類型系統來檢查這個函數是否正確。
這個過程叫做模板的「特化」,它發生在編譯期,當編譯器發現模板函數、模板類被使用(注意,不是定義)的時候進行的。這個系統實際上比較像宏,但是比宏更為智能。
很明顯,編譯器必須知道模板如何特化這個函數,因此模板函數的實現,必須在「使用點」之前,因此模板庫只能通過頭文件庫的形式來提供。

『拾』 office2007如何在編譯過文件以後替換PPT模板

我也想知道如何實現這個功能。求大俠解答啊!

熱點內容
java返回this 發布:2025-10-20 08:28:16 瀏覽:821
製作腳本網站 發布:2025-10-20 08:17:34 瀏覽:1086
python中的init方法 發布:2025-10-20 08:17:33 瀏覽:792
圖案密碼什麼意思 發布:2025-10-20 08:16:56 瀏覽:957
怎麼清理微信視頻緩存 發布:2025-10-20 08:12:37 瀏覽:848
c語言編譯器怎麼看執行過程 發布:2025-10-20 08:00:32 瀏覽:1201
郵箱如何填寫發信伺服器 發布:2025-10-20 07:45:27 瀏覽:421
shell腳本入門案例 發布:2025-10-20 07:44:45 瀏覽:300
怎麼上傳照片瀏覽上傳 發布:2025-10-20 07:44:03 瀏覽:977
python股票數據獲取 發布:2025-10-20 07:39:44 瀏覽:944