他のコードが入ったテンプレートがあるとします。 g ++はテンプレートのすべてのバージョンで同じコードをすべて再生成しますか?例えばg ++テンプレートインスタンシエーターはどのくらいスマートです(テンプレートの膨張を避ける)
:
template <typename> T
T parseSomething(const std::string& data) {
// Some state variables go here
enum State {state1,state2,state3} state;
for(std::string::const_iterator i=data.begin();i!=data.end();++i) {
// Some big testy stuff to see if we got in the right place
switch (state) {
case state1: {
switch (*i) {
case f: // ...
// ... lots of switchy stuff here ..
return T(*i);
}
}
はだからFUNCに..本当にテンプレートを必要とする唯一のビットは、リターンT(* I)ラインです。
私はそれを4つの異なるTsでインスタンス化すると仮定します。
parseSomething<float>(data);
parseSomething<int>(data);
等
は、G ++のすべての他のコード(ループ及びスイッチ部)毎にTに対して別々の時間を生成しますか?
または、スイッチとループを生成するだけで十分です。それから、各Tに対して... return T(* i)を生成します。ライン?
私はテストを試みましたが、-O0を使用するとどこでもスイッチが複製されていましたが、-O2以上ではわかりにくいものでした。私はASMを解読することができませんでした、それは...賢くように見えたが、それはとてもスマートだった:)
ここで私がテストに使用しようとしている私のサンプルプログラムです。
g++ -std=c++0x -fverbose-asm -ggdb3 -fvar-tracking-assignments -O6 -march=native codegen.cpp
を実行する:コンパイルするに
gdb --args ./a.out asdf1111
偏執コードバージョン:私が使用したい
#include <iostream>
#include <string>
using namespace std;
char getSomething(const string& myString) {
for(auto myPlase=myString.begin();myPlase!=myString.end();++myPlase) {
if (*myPlase == 'f') {
return *(myPlase+1);
}
}
}
template <typename T>
T getSomething(const string& myString) {
return T(getSomething(myString));
}
int main(int argc, char** argv) {
string base = argv[1];
float myFloat = getSomething<float>(base);
int myInt = getSomething<int>(base);
char myChar = getSomething<char>(base);
//string newString = getSomething<string>(base);
cout << myFloat << " " << myInt << " " << myChar << endl;
}
コードバージョン:
#include <iostream>
#include <string>
using namespace std;
template <typename T>
T getSomething(const string& myString) {
for(auto myPlace=myString.begin();myPlace!=myString.end();++myPlace) {
if (*myPlace == 'f') {
return T(*(myPlace+1));
}
}
}
int main(int argc, char** argv) {
string base = argv[1];
float myFloat = getSomething<float>(base);
int myInt = getSomething<int>(base);
char myChar = getSomething<char>(base);
//string newString = getSomething<string>(base);
cout << myFloat << " " << myInt << " " << myChar << endl;
}
実際のプログラムでは、コードを生成するためにragelを使用しています。これは約1200行です。私はそれをテンプレート関数に変えたいと思います。テンプレートのメインビットは戻り値の型ですが、すべての型に対してそれらの1200行が再生成されるのを見たくありません。 – matiu
GCCだったら、問題のコードをどのように生成しますか? –
もちろん、実際の質問は:妄想のコードの例では、 'getsomething'の呼び出しが:) –