У меня есть код, который использует шаблоны, поэтому я могу переключаться между float, real, double, для точности вычислений или экономии памяти. Теперь я бы хотел, чтобы пользователь выбирал точность при каждом выполнении, но я не уверен, как должен.
Позвольте сказать в моем main.cpp. У меня есть
// main.cpp
Object<double> obj;
obj.doSomething();
Есть ли способ "установить" используемый тип? Что-то вроде следующего?
//main.cpp
std::cout << "Choose Precision ": << std::endl;
std::cin >> PRECISION; // eg float or double
? fix precision and use generic code below with it ?
Object<PRECISION> obj;
obj.doSomething();
ОБНОВИТЬ
Теперь ясно, что я не могу во время выполнения. Благодарю.
Могу ли я использовать общий шаблонный код в основном, так что у меня есть только одна строка для редактирования, чтобы скомпилировать код при разных настройках?
Обновление от Kevin Cadieux: typedef double MyPrecision;
Вы не можете установить тип шаблона во время выполнения, но вы можете выбрать, какую специализацию шаблона использовать. Например:
template <typename T>
void doStuff<T>()
{
Object<T> obj;
// do something with obj
}
int main()
{
// same PRECISION getting code
switch (PRECISION) {
case (x) :
doStuff<double>();
break;
case(y) :
doStuff<float>();
break;
....
}
Нет, потому что шаблоны работают во время компиляции, вы пытаетесь изменить типы во время выполнения. Если вы хотите сделать это, вы должны использовать наследование и полиморфизм.
Проще говоря: нет. Во время компиляции возникают экземпляры шаблонов. Ваша переменная PRECISION будет известна только во время выполнения, поэтому вы не сможете использовать ее для создания шаблона.
Как сказал Джон, в таких случаях (и в любых других случаях, когда поведение известно только на основе условий выполнения), было бы наиболее подходящим использовать полиморфизм.
Возможно, у вас может быть иерархия классов, подобная этой:
class SomePrecisionBase
{
virtual double compute() = 0; //Or whatever
};
class MySuperPreciseClass
{
virtual double compute(); //Super precise computation
};
class MyNotSoPreciseClass
{
virtual double compute(); //Not so precise computation
};
Затем, чтобы построить правильный класс, используя пользовательский ввод из std::cin
, вы, вероятно, захотите написать заводскую функцию следующим образом:
SomePrecisionBase* factory(int precision)
{
//Construct a concrete class here and return it as a SomePrecisionBase pointer
//Also consider using an std::shared_ptr instead of a raw pointer
}
РЕДАКТИРОВАТЬ
Но это определенно странно, если вы просто хотите выбирать между двойным и одиночным вычислением с плавающей запятой. В таком случае я предпочел бы подход juanchopanza.
Кроме того, у вас может быть typedef где-то в вашем коде, что-то вроде:
typedef double MyPrecision;
Если вы хотите принять решение о компиляции, то вы можете создавать шаблоны с помощью MyPrecision и иметь только одно место для изменения, если вы передумаете.