Я отвечу для случая работы с простым форматом ввода:
12345 + 6789
1) вы не модифицируете входную строку, поэтому, если имеем дело со стандартом от c++17, то лучше в функцию принимать явно 
string_view или 
const string_view&, если ниже, то принимать надо 
const string&. 
2) если уж принимаем что-то строкоподобное, то смело пользуемся функцией-членом 
::find, которая есть и в строке и в вью. С её помощью можно найти сразу позицию арифметического символа. Для простого случая, даже не нужен обход от найденной позиции к началу строки и к концу строки для проверок 
std::isspace, является ли символ пробелом, поскольку мы можем сразу слать в atoi для левого числа например 
string_view::substr(0, opPos - 1). И, получится, только один if/switch, который будет сопоставлять символ операции, например, с указателем на функцию.  
...
int plus(int left, int right) { return left + right; }
using CalculatorFunction = int (*)(int, int);
...
CalculatorFunction operation;
...
switch (opChar):
case '+': operation = plus;
...
3) настоятельно рекомендую после этого реализовать нормальный простой калькулятор, а потом третьим заходом добавить поддержку скобок, hex oct бинарную и с мантиссой нотации записи чисел, операцию степени и корня. 
Нормальный - имеется ввиду, что в калькулятор входит строка, которая является корректным арифметическим выражением.  В этом случае нужно ещё иметь дело с разделителями. По-хорошему,  решение состоит из нескольких этапов: 
 - на первом логическом этапе функция парсит выражение и сохраняет в контексте или возвращает контейнер с токенами, (или прерывает весь процесс из-за плохой строки). В вашем варианте, задача однопоточная, поэтому можно воспользоваться функцией 
strtok, чтобы удобно извлечь строковое значение токена по входной строке от разделителя до разделителя.
 - как вариант, токены могут быть структурами с членом string_view на строковые представления и членом на тип токена (число, операция).
 - на втором логическом этапе мы считываем последовательность токенов и делаем какое-то действие:
 
	- считали число - ожидаем за ним токен операции 
 
- если оказался не токен операции - бросаем исключение о некорректном арифметическом выражении, иначе - подготавливаем аргументы и  кормим функцию evaluate<T>( Token::kOperation op, T arg1, T arg2), для случая, если операции нужно два аргумента, то первый уже считан, а второй будет в последовательности токенов за операцией. Результат evalaute записываем в переменную результата, которая, кстати говоря, типа double.
 
- продолжаем движение по последовательности токенов до конца, контейнером может быть std::list, когда добрались до конца, возвращаем результат.