Шаблон специализированный метод - PullRequest
0 голосов
/ 26 сентября 2018

У меня есть метод, который является шаблонным, и я хочу добавить специализацию.Для функции я написал бы

template<> T function<typename T>() { /* ... */ }

Как мне сделать это для метода?

Вот минимальный неудачный пример, где мне нужно специализировать recv для <char>.

#include <vector>

class recver_t {
public:

    // recv should work for chars, ints, and lists of those.

    template <typename list_t, typename elem_t>
    list_t recv() {
        list_t list;
        for (int i = 0; i < 10; ++i) {
            list.push_back(recv<elem_t>());
        }
        return list;
    }

    // How to specify this template?
    // It needs to be a template taking 1 typename, but specialized for <char>
    // I need the template spec because I am overloading by return-type.
    char recv() {return '\0';}

    // likewise, but for int
    //int recv() {return 0;}
};

int main() {
    recver_t recver;
    // std::vector<char> result = recver.recv<std::vector, char>();
    // EDIT: should be this
    std::vector<char> result = recver.recv<std::vector<char>, char>();
}
  • Я мог бы опустить спецификацию шаблона и полагаться на перегрузку функций C ++, но это не сработает, потому что я перегружаюсь типом возврата.

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Вы можете сделать это, чтобы иметь специализированные обобщенные методы:

char recv() {
    cout << "Specialized method" << endl;
    return '\0';
}

template <typename T>
T recv() {
    cout << "General method" << endl;
}

и затем вы можете назвать это так:

recver.recv();
recver.recv<bool> ();

вывод будет:

Specialized method
General method

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

0 голосов
/ 26 сентября 2018

Если вы хотите сделать ТОЛЬКО специализации, то:

Сначала создайте основное определение шаблона:

template<typename T>
T recv();

Затем создайте только специализации:

template<>
char recv<char>() {return '\0';}

// likewise, but for int
template<>
int recv<int>() {return 0;}

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

Поэтому Вам необходимо удалить либо конкретные специализации:

template<> 
float recv<float>() = delete;

иливсе другие специализации, но тогда это определение должно заменить основное определение:

template<typename T> 
T recv() = delete;
...