What you are looking for is called a variant or a tagged union/algebraic sum type.
It goes by many names, but the pattern of "represent a single value that could be 1 of N types" is very common in programming languages and is usually hard-coded into variables (Python, Ruby, Lisp, JavaScript, etc.) or represented through an explicit union/enum/sum type (C++, C, Rust, Java, C#, etc.).
If you can use C++17 and later, you can just use std::variant<int, float, std::string> to do as you please, and then use std::get<T>, std::holds_alternative<T>, and std::visit<R, Visit, ...Variants> to generically query, get, and perform actions depending on what type of variant it is.
The (very rough and first-draft) code below should work if both of the variant values have the same type contained within them, but still fail for other cases. I have also taken the liberty to provide some dummy implementations for the functions you used but did not define:
#include <variant>
#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;
bool is_int(const string& s) {
try {
stoi(s);
return true;
} catch (invalid_argument e) {
return false;
}
};
bool is_float(const string& s){
try {
stof(s);
return true;
} catch (invalid_argument e) {
return false;
}
};
bool is_string(const string& s){
return true;
};
string GetFrom(size_t first_index, size_t last_index, const string& s){
return s.substr(first_index, last_index-first_index);
};
int convert_to_int(const string& s){
return stoi(s);
}
float convert_to_float(const string& s) {
return stof(s);
}
int main() {
variant<int, float, string> value1, value2;
string val1 = "123.43";
string val2 = "4566.123";
if (is_int(val1)) {
value1 = convert_to_int(val1);
} else if(is_float(val1)) {
value1 = convert_to_float(val1);
} else {
value1 = GetFrom(1,val1.size()-1,val1);
}
if (is_int(val2)) {
value2 = convert_to_int(val2);
} else if (is_float(val2)) {
value2 = convert_to_float(val2);
} else {
value2 = GetFrom(1,val2.size()-1,val2);
}
variant<int, float, string> result;
if (holds_alternative<int>(value1) && holds_alternative<int>(value2)) {
result = get<int>(value1) + get<int>(value2);
} else if (holds_alternative<float>(value1) && holds_alternative<float>(value2)) {
result = get<float>(value1) + get<float>(value2);
} else {
result = get<string>(value1) + get<string>(value2);
}
cout << holds_alternative<int>(value1) << endl;
visit([](const auto& val) {
cout << val << endl;
}, result);
return 0;
}
NOTE: your strategy of checking for variable type from a string is probably best served by taking advantage of regular expressions (regex), which are tailor-made and theoretically sound to perform the string-matching you desire. Most professional applications will use some sort of regex or context-free parsing algorithm to parse simple types of strings or infinitely-nestable strings.