Если у меня есть шаблон с кучей другого кода в нем.Будет ли 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);
}
}
Так что в этой функции ... единственное, что действительно нуждается в шаблонах, этострока возврата T (* i).
Предположим, что я создал его с 4 различными Ts, например.
parseSomething<float>(data);
parseSomething<int>(data);
и т. д.
Будет ли g ++ генерировать весь этот другой код (цикл и части переключателя) отдельное время для каждого T?
Или это было бы достаточно разумно, чтобы генерировать переключатели и циклы только один раз ... затем для каждого T .. генерировать возврат T (* i);line?
Я пробовал тестировать, и с -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;
}