Как специализировать конструктор класса шаблона в C++
Я практикую C++ и хочу реализовать несколько структур данных с помощью шаблонов.
Я хочу создать конструктор дляList<char>
который принимает C++ в качестве параметра, но я не хочу создавать такой конструктор для остальных типов (так как не имеет особого смысла создаватьList<double>
изstring
, например).
Есть ли способ добиться этого на С++?
Вот мой код:
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
template <typename T> class CollectionInterface {
public:
virtual T get();
virtual void set(int index, T value);
virtual void add(T value);
virtual int length();
};
template <typename T> class ListItem {
public:
T value;
ListItem* next;
ListItem* prev;
};
template <typename T> class List: public CollectionInterface<T> {
public:
List(){}
List(T* arr, int length){
init(arr,length);
}
~List(){
}
protected:
void init(T* arr, int length){
}
ListItem<T>* first;
ListItem<T>* last;
};
template<char> class List<char> {
public:
List<char>(string s){
char char_array[s.length() + 1];
strcpy(char_array, s.c_str());
this->init(char_array,s.length());
}
};
int main()
{
List<char> list("Hello World!");
//cout << "Hello World!" << endl;
return 0;
}
Он показывает следующие ошибки:
Строка 40: Частичная специализация «Списка» не использует ни один из параметров шаблона.
Строка 45: нет члена с именем 'init' в 'List<char>'
1 ответ
Чтобы делать то, что вы хотите, вам не нужно специализироваться на всемList
сорт. Просто предоставьте свойList<T>
класс с перегруженным конструктором дляstring
ввода, а затем используйте SFINAE, чтобы отключить этот конструктор для не-char
списки, например:
template <typename T> class List: public CollectionInterface<T> {
public:
...
template <typename U = T>
List (typename enable_if<is_same<U, char>::value, string>::type const &s)
{
init(const_cast<char*>(s.c_str()), s.length());
}
...
};