В коде используются два разных алгоритма. Какой из них выбран, определяется во время выполнения параметром (например, true или false). Я не хочу использовать операторы if каждый раз, когда появляется алгоритм.

Поэтому вместо того, чтобы каждый раз писать следующее

if (parameter==true)
    algorithmOne();
else
    algorithmTwo();

Я хочу установить алгоритм в начале, например

if (parameter==true)
    algorithm()=algorithmOne();
else
    algorithm()=algorithmTwo();

И с этого момента используйте только «алгоритм()».

Как выбрать алгоритм в начале в зависимости от параметра после того, как код уже скомпилирован?

c++
2
Oliver 4 Фев 2022 в 13:52
2
Звучит как задание для функции или указателя метода.
 – 
Refugnic Eternium
4 Фев 2022 в 13:53
Проверьте эти две ссылки 1) stackoverflow.com/questions/3053561/… и этому, 2) stackoverflow.com/questions/9864125/c11-how-to-alias-a-function
 – 
iwrestledthebeartwice
4 Фев 2022 в 13:54
Множество различных способов, шаблон вашего кода, использование указателя на функцию или std::function, использование шаблона наследования и стратегии,...
 – 
Jarod42
4 Фев 2022 в 13:57

3 ответа

Ты почти там:

auto algorithm = parameter ? algorithmOne : algorithmTwo.

Нет (), здесь вы не пытаетесь вызвать какую-либо функцию.

3
MSalters 4 Фев 2022 в 13:55
1
И обе функции, конечно же, должны иметь одинаковые типы параметров и возвращать один и тот же тип.
 – 
Sebastian
4 Фев 2022 в 14:21
@Sebastian: Действительно, иначе они не были бы взаимозаменяемы.
 – 
MSalters
4 Фев 2022 в 14:24

Ответ, который вы ищете, скорее всего, является указателем на функцию/метод.

Синтаксис указателя на функцию следующий:

typedef void (*MyFunctionPointer)();
MyFunctionPointer *algorithm;

void function(bool parameter)
{
    if (parameter)
        algorithm = &myFirstAlgo;
    else
        algorithm = &mySecondAlgo;
}

void anotherFunction()
{
    algorithm();
}

Обратите внимание, что этот подход работает для C, C++03 и C++11. Если вы хотите использовать auto в глобальной области видимости, вам нужно указать значение по умолчанию.

1
Refugnic Eternium 4 Фев 2022 в 13:56

Объектно-ориентированным способом сделать это было бы определение базового класса с интерфейсом алгоритма:

class AlgorithmBase
{
public:
    virtual void algorithm() = 0;
    virtual ~AlgorithmBase() {}  // virtual destructor may be needed
};

Затем реализуйте классы для различных реализаций алгоритма:

class AlgorithmOne: public AlgorithmBase
{
public:
    virtual void algorithm();
};

void AlgorithmOne::algorithm()
{
   ...
}

И аналогично для AlgorithmTwo и других реализаций.

Теперь вы можете определить указатель на объект алгоритма, содержащий выбранную реализацию, и использовать его всякий раз, когда алгоритм должен выполняться:

   AlgorithmBase *algorithm = 0;
   if(parameter)
   {
      algorithm = new AlgorithmOne();
   }
   else
   {
      algorithm = new AlgorithmTwo();
   }

   ...
   algorithm->algorithm();  // Call the selected algorithm

   ...
   delete algorithm;  // Destroy algorithm instance before exiting
1
nielsen 4 Фев 2022 в 14:23