Установка типа шаблонного кода при каждом выполнении

0

У меня есть код, который использует шаблоны, поэтому я могу переключаться между 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;

Теги:
templates

3 ответа

4
Лучший ответ

Вы не можете установить тип шаблона во время выполнения, но вы можете выбрать, какую специализацию шаблона использовать. Например:

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;
  ....
}
  • 0
    О, я сначала неправильно понял ваш ответ. Оказывается, это именно то, что мне нужно, спасибо.
4

Нет, потому что шаблоны работают во время компиляции, вы пытаетесь изменить типы во время выполнения. Если вы хотите сделать это, вы должны использовать наследование и полиморфизм.

1

Проще говоря: нет. Во время компиляции возникают экземпляры шаблонов. Ваша переменная 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 и иметь только одно место для изменения, если вы передумаете.

  • 0
    У меня есть много шаблонных классов, все используют typename T для точности, но определенно о чем подумать, спасибо.
  • 1
    @ user2287453 Если вы абсолютно хотите отложить решение до времени выполнения, то я бы пошел на то, что сказал juanchopanza. В противном случае вы можете использовать typedef, как показано в моем редактировании, но тогда он должен быть известен во время компиляции.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню