0

I am learning C++ templates.I created a template class for addition of two strings but I'm getting folloing error: Please help me to understand this 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;
}
1
  • you declare parameters in your constructor as pointers to T, but you pass strings as arguments in main. Try to change your paramters type to const &T Commented Jul 23, 2013 at 19:13

3 Answers 3

4

What? No. This isn't what templates are used for

You use strcat on your templated objects (actually, on T*, so on pointers to your object)

strcat accepts only char *. So T has to be char for it to work. If you know T is char, then it isn't a template as you know what it is. (btw - you have another bug that returnval should be T*, and you are using it uninitialized)

You seem to miss the whole concept of templates - which is OK since you are learning.

See - the sentence "I want to use templates to add two strings" is wrong - as you don't have any unknowns! You want to add 2 strings, you know what your type is. It isn't template.

Template would be "I want to add two lists of an unknown type" (then you can't use strcat obviously, nor can you assume your lists are "zero delimited" as that is only true for c style strings).

Sign up to request clarification or add additional context in comments.

Comments

3

Your template parameter is std::string, so your constructor

TheNameHolder(T *first, T *last)

expects two pointers to std::string. You are passing it const arrays of char (string literals). It seems to me you can express everything in terms of 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();
}

Note it isn't completely clear whether you need a class template here. The only advantage of this is that you can also use std::wstring or any other string type that supports initialization from a string literal and the + operator.

2 Comments

This may just be my ignorance regarding namespaces, but, since he's using "namespace std", wouldn't his <string> be assumed to be <std::string>?
@BenC. Yes, that is my assumption. My code differs because I never using namespace std, and am in the habit of qualifying standard library types with the std:: namespace. Oh, maybe you got confused by my badly spelt std::wstring.
0

As was stated above, this would be the wrong place to use templates since you already know the data type. However, in the case where you may actually wish to "add two lists of an unknown type", you can use template specializations to deal with specific (in this case non-numeric) data types such as strings. You would specialize this template as follows:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.