Шаблонный метод C ++, изменяющий поведение на основе шаблонного класса - PullRequest
2 голосов
/ 19 мая 2011

Я пытаюсь написать шаблонный метод c ++. Ниже приведен пример кода, демонстрирующий, что я хочу сделать в методе.

template<class T>
void method(T value) {
    // This string should change based on type T 
    char *str = "Int" or "Float" or .. ;   
    ...
    ...
    std::cout << value << " is of type " << str << std::cout;
}

По существу, поведение (строковое значение в этом примере) метода будет меняться в зависимости от типа T. Как я могу сделать это с шаблоном?

Ответы [ 3 ]

11 голосов
/ 19 мая 2011

Вы можете специализировать свой шаблон для разных типов.Если вы начнете с базового случая:

template <class T>
void method(T value);

Затем вы можете объявить другое поведение для любого конкретного значения T:

template <>
void method<int>(int value) {
  // special behavior
}

и так далее.Но так как меняется только тип ввода вашей функции, вам действительно не нужны шаблоны в этом случае!Вы можете просто перегружать свою функцию различными типами аргументов:

void method(int T);
void method(float T);
void method(void* T);

EDIT : Использование специализации шаблона для получения имени типа и использования его в другом шаблоне функции:

template <class T>
std::string type_to_string();

template <>
std::string type_to_string<int>() {
  return "int";
}

template <>
std::string type_to_string<float>() {
  return "float";
}


template <class T>
some_other_function(T value) {
  std::cout << value << " is a " << type_to_string<T>() << std::endl;
}

Конечно, вы все еще можете сделать это без шаблонов:

std::string type_to_string(int) {
  return "int";
}

some_other_function(int value) {
  std::cout << value << " is a " << type_to_string(value) << std::endl;
}

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

2 голосов
/ 19 мая 2011

С макушки головы можно двумя способами:

  1. Возможно, у T может быть метод, который возвращает соответствующую строку, и все ваши T предоставляют этот метод.

Тогда вы можете сказать:

char * str = T.getTheAppresponString ();

  1. RTTI и dynamic_cast. Смотри http://en.wikipedia.org/wiki/Run-time_type_information.
0 голосов
/ 19 мая 2011

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

template <typename T> CustomBehavior;

template <typename T>
void
function( T value )
{
    //  ...
    CustomBehavior<T>::specialized(...);
    //  ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...