Я действительно надеялся, что смогу достичь этого, используя шаблоны C++ (11), но я столкнулся с некоторыми проблемами здесь. Таким образом, у нас есть пользовательский объект-указатель, который внутри может быть любого из этих типов: список объектов собственного типа/int/a char/bool/long/double/char * или любой другой примитивный тип, и это определяется флаг, который хранится в этом объекте. Существуют глобальные методы получения значений конкретных типов из этого объекта.C++ условные шаблоны Компиляция на основе типа данных
Теперь моя цель проста. Я знаю, что для моего случая, мой объект находится список таких объектов, поэтому я хотел бы написать такую функцию, как это общий сценарий:
template <typename T>
std::vector<T> List_To_Vector(Object& list)
{
std::vector<T> vec;
int listSize = Func_Size(list);
for (int i = 0; i < listSize; ++i)
{
//let's say this function gives list items one by one
Object arg = Func_Next(list);
if (std::is_same<T, int>::value || std::is_same<T, unsigned int>::value)
vec.push_back((T)Func_IntValue(arg));
else if (std::is_same<T, float>::value || std::is_same<T, double>::value)
vec.push_back((T)Func_DoubleValue(arg));
else if (std::is_same<T, std::string>::value || std::is_same<T, char*>::value)
vec.push_back((T)Func_StringValue(arg)); //Func_StringValue returns char*, so conversion to std::string should work
else if (std::is_same<T, bool>::value)
vec.push_back(Func_BoolValue(arg));
else if (std::is_same<T, char>::value)
vec.push_back(Func_CharValue(arg));
vec.push_back(val);
}
return vec;
}
int main()
{
Object listContainingStrings = GetListOfNames();
Object listContainingNumbers = GetListOfNumbers();
std::vector<string> vec1 = List_To_STD_Vector<string>(listContainingStrings);
std::vector<int> vec2 = List_To_STD_Vector<int>(listContainingNumbers);
return 0;
}
Проблема заключается в том, C++ жалуется здесь, как он пытается скомпилировать код, принимающий T = std :: string, и int для string или float для преобразования строк завершится с ошибкой. То, что я действительно хотел здесь, это способ скомпилировать внутреннюю часть кода, когда тип определяется как int, а не какой-либо другой тип. Я могу использовать специализацию или перегрузку функции шаблона, но тогда я думаю, что она действительно побеждает цель шаблонов здесь, и я мог бы просто написать 8 разных функций для 8 разных типов (например, List_To_String_Vector, List_To_Int_Vector и т. Д.).
Я также пробовал еще один взломать, используя reinterpret_cast < T * > по адресу каждого типа возврата, а затем разыменовывая его для добавления в вектор. Это сработало, но есть предупреждения компилятора, и я думаю, что это неопределенное поведение.
Есть ли способ сделать это правильно?
Спасибо!
Это выглядит очень плохой дизайн. И если вы хотите, чтобы объект обрабатывал несколько типов, то почему бы не использовать ['std :: any'] (http://en.cppreference.com/w/cpp/utility/any) из предстоящего стандарта C++ 17 ? Или если у вас его еще нет, то [Boost any] (http: //www.boost.орг/док/ЛИЭС/1_63_0/DOC/HTML/any.html)? –
Почему ваша отдельная функция 'Func_ * Value' вместо одного шаблона или набора перегрузки? – Quentin
@Quentin: Из-за устаревшего кода, а также для выполнения языка программирования Схемы для совместимости с C++. –