Is it really necessary to go through the process of accepting a string as input and convert it to a numeral to perform the calculation?
It isn't strictly necessary but it does enforce good habits.  Let's assume you are going to ask for 2 numbers from the users and use something like
std::cout << "Enter first number: ";
std::cin >> first_number;
std::cout << "Enter second number: ";
std::cin >> second_number;
For the first number the user enters 123bob.  operator>> is going to start reading it in and once it hits b it is going to stop and store 123 into first_number.  Now the stream has bob still in it.  When it asks for the second number since bob is still in the stream it will fail and second_number will get set to 0.  Then the program will continue on and you will get garbage output because you accepted garbage input.
Now, if you read in as a std:string and then convert to what you want it makes it easier to catch these types of errors.  getline(std::cin, some_string); would get all of 123bob out of the input buffer so you don't have to worry about having to clean it up.  Then using stoi (or any of the stox functions) it will read the valid value of of it.  The functions also have a second parameter which is a pointer to a size_t and if you pass it one it will store the position of the first unconverted character in the string and you can use that to tell if the entire input string is valid or not.  So, if you had
std::string input;
std::cout << "Enter some number: ";
std::getline(std::cin, input);
std::size_t pos;
double number = std::stod(input, &pos);
if (pos == input.size())
    std::cout << "valid input\n";
else
    std::cout << "invalid input\n";
Then 1.23bob would cause invalid input to print where 1.23 cause valid input to print.  You could even use this in a loop to make sure you get only valid input like
double number;
do
{   
    std::string input;
    std::cout << "Enter some number: ";
    std::getline(std::cin, input);
    std::size_t pos;
    number = std::stod(input, &pos);
    if (pos != input.size())
        std::cout << "invalid input\n";
    else
        break;
} while(true)
TL;DR: If you rely on the user to only input valid input eventually you are going to get burned. Reading in as a string and converting offers a consistent way to ensure that you are only getting good input from your user.