Специализация шаблона или перегрузка функций

Я знаю, что есть и другие подобные вопросы, но они не очень ясны.

Теперь я чувствую, что это глупый вопрос, потому что я уверен, что у меня уже есть ответ, но все же позвольте мне спросить.

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

template<class T>
void ConvertValue(std::string str, T &variable)
{
    variable = static_cast<T>(str);
}

так вроде нормально правильно? Но дело в том, что вы не можете преобразовать строку, чтобы сказать, int или float, поэтому мне пришлось бы делать специализацию шаблона для int и float, а для других типов, в которые он не может преобразоваться, поэтому я спрашиваю, должен ли я иметь что-то вроде этого:

void ConvertValue(std::string str, int &variable) { variable = atoi(str.c_str()); }
void ConvertValue(std::string str, float &variable) { ... }
void ConvertValue(std::string str, double &variable) { ... }
void ConvertValue(std::string str, std::vector<int> &variable) { ... }

..и т.д

или я должен использовать специализацию шаблона? Какой из них будет иметь больше смысла? Я склоняюсь к перегрузке функций, потому что у большинства типов будет своя собственная функция преобразования, поэтому, поскольку они немного отличаются, перегрузка функций имеет для меня логический смысл, но я не знаю, упускаю ли я что-то.

Должен ли я придерживаться перегрузки функций? Или переключиться на специализацию шаблона?


person CodingMadeEasy    schedule 30.04.2013    source источник
comment
Я бы не стал предполагать статическое приведение by-val std::string к произвольной типизированной переменной даже с work, а тем более нормально. Но вы, вероятно, можете выполнить то, что хотите, с некоторой помощью strstream.   -  person WhozCraig    schedule 01.05.2013
comment
Это кажется странным. Что вы ожидаете, если вы скажете, преобразовали строку в список. Список‹строка›? Список‹char› с каждой записью одной из строк символов? Как это будет обрабатывать объекты, созданные пользователем? Похоже, что stringstream должен заботиться о стандартных целых числах, числах с плавающей запятой и т. д. Возможно, вам нужна версия шаблонного контейнера. Но чего именно вы надеетесь добиться здесь?   -  person Muckle_ewe    schedule 01.05.2013


Ответы (4)


Если внутренности функции должны быть разными для каждого типа и потенциально включать проверки типов, проще и чище иметь несколько функций.

Если, с другой стороны, у вас есть куча классов с методом toString() для преобразования. Тогда вы будете использовать шаблон, потому что внутренности всегда будут одинаковыми.

person Jean-Bernard Pellerin    schedule 30.04.2013
comment
+1 за предложение использовать шаблон, если повторное использование кода является основной целью. - person Jonny Dee; 01.05.2013

Я бы использовал std::istringstream:

template <typename T>
T ConvertValue(const std::string& str)
{
    std::istringstream iss(str);

    T ret;
    if (!(iss >> ret))
    {
        throw std::bad_cast("Failed!");
    }

    return ret;
}
person Jesse Good    schedule 30.04.2013

Это должен быть ответ на ваши вопросы:

как получить переменную typeof в C++

и да, это должна быть специализация шаблона.

person Mehdi Karamosly    schedule 30.04.2013

Короткий ответ :

Ты прав. Перегрузка функций имеет больше смысла. Специализация базового шаблона функций не перегружает.


Длинный ответ

специализация базового шаблона функций - гражданин класса 2, функции - гражданин первого класса.

Если вы напишете перегруженную функцию, никто не сможет написать что-либо, перегружающее или скрывающее ваш код, без ошибки компилятора. Если вы напишите специализацию базового шаблона функции, любой может перегрузить ее перегрузкой функции, соответствующей этой сигнатуре специализации базового шаблона функции. (да, программист, пишущий специализацию, будет в бешенстве от вашей функции, но ему придется с этим смириться).

Если вам нужен лучший вопрос для лучшего ответа, прочитайте Почему бы не специализировать шаблоны функций? : http://www.gotw.ca/publications/mill17.htm

person splinux    schedule 15.05.2013