2013-07-23 5 views
0

Я изучаю C++ templates.I создал класс шаблонов для добавления двух строк , но я получаю следующую ошибку: Пожалуйста, помогите мне понять эту ошибку.C++ Template Определение класса get error

main.cc:65:52: error: no matching function for call to TheNameHolder<std::basic_string<char> >::TheNameHolder(const char [8], const char [7])

using namespace std; 

template <class T> 
class TheNameHolder{ 
    T *a, *b; 
    public: 
    TheNameHolder(T *first, T *last) 
    { 
    a= first; 
    b= last; 
    } 
    T getName(); 
}; 

template <class T> 
T TheNameHolder<T> :: getName() 
{ 
    T returnVal; 
    returnVal = strcat (returnVal,a); 
    returnVal = strcat (returnVal, " "); 
    returnVal = strcat (returnVal, b); 
    return returnVal; 

} 


int main() 
{ 

    TheNameHolder <string> obj ("Hi", ""); 
    cout << obj.getName(); 
    return 0; 
} 
+0

вы объявляете параметры в конструкторе в качестве указателей на T, но передавать строки в качестве аргументов в основной. Попытайтесь изменить свой тип параметров на const & T –

ответ

4

Что? Нет, это не то, что шаблоны используются для

используется strcat на ваших шаблонных объектов (на самом деле, на T*, поэтому на указатели к объекту)

strcat принимает только char *. Таким образом, T должен быть символом для его работы. Если вы знаете, T is char, значит, это не шаблон, так как вы знаете, что это. (btw - у вас есть еще одна ошибка: returnval должен быть T*, и вы используете его неинициализированным)

Вы, кажется, пропустите всю концепцию шаблонов - это нормально, так как вы учитесь.

См. - предложение «Я хочу использовать шаблоны для добавления двух строк» ​​неверно - поскольку у вас нет неизвестных! Вы хотите добавить 2 строки, вы знаете, что такое ваш тип. Это не шаблон.

Шаблон должен быть «Я хочу добавить два списка неизвестного типа» (тогда вы не можете использовать strcat, и вы не можете считать, что ваши списки «с нулевым разделителем», как это верно только для строк стиля c) ,

3

Ваш параметр шаблона std::string, так что ваш конструктор

TheNameHolder(T *first, T *last) 

ожидает два указателя на std::string. Вы передаете ему константные массивы char (строковые литералы). Мне кажется, вы можете выразить все, что с точки зрения std::string:

template <class T> 
class TheNameHolder{ 
    T a, b; 
    public: 
    TheNameHolder(const T& first, const T& last) : a(first), b(last) 
    { 
    } 
    T getName() { return a + " " + b; } 
}; 

int main() 
{ 
    TheNameHolder<std::string> obj("Hi", ""); 
    std::cout << obj.getName(); 
} 

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

+0

Это может быть просто мое невежество относительно пространств имен, но поскольку он использует «пространство имен std», не будет ли его быть ? –

+0

@BenC. Да, это мое предположение. Мой код отличается тем, что я никогда не «использовал пространство имен std», и я привык отбирать стандартные типы библиотек с пространством имен 'std ::'. О, может быть, вы запутались в моей плохо написанной 'std :: wstring'. – juanchopanza

0

Как было указано выше, это было бы неправильным местом для использования шаблонов, поскольку вы уже знаете тип данных. Однако в случае, если вы действительно хотите «добавить два списка неизвестного типа», вы можете использовать специализированные шаблоны для обработки конкретных (в данном случае нечисловых) типов данных, таких как строки. Вы бы специализироваться этот шаблон следующим образом:

template <> class TheNameHolder <std::string> { ... };

Смежные вопросы