Question

this might be question that someone asked before but i can't find it...

i have a class in a .hpp file :

class A{
    public:
        A(){//constructor}
        ~A(){//destructor}
        //some public methods and arguments

        template<typename Type>
            void func(Type t){//do something for numbers}

    private:
        //some private methods and arguments
}

The template method should work for int, double... but not for string. Thus in my .hpp file, I defined what func does for numbers and in my .cpp file I wrote :

template<>
void A::func(std::string t){ // do something in that case}

But when I use the function func with std::string, the program calls the methods for numbers... So I replaced the .hpp file by :

class A{
    public:
        A(){//constructor}
        ~A(){//destructor}
        //some public methods and arguments

        template<typename Type>
            void func(Type t){//do something for numbers}
        void func(std::string s);

    private:
        //some private methods and arguments
}

and my .cpp file became :

void A::func(std::string t){ // do something in that case}

and then everything works !

my question is, is this the correct way to do that ?

Was it helpful?

Solution

That's not a partial specialization (there are no template parameters left un-specialized) it's an explicit specialization.

Templates must be visible to the code that uses them, if you don't declare the specialization in the header file then code that tries to call A::func with a string will instantiate the primary template (the one for numbers) and use that, because they don't know the `string specialization even exists.

So you must (at least) declare the specialization in the header in order for it to be usable outsde the .cpp file:

template<>
void A::func(std::string t);

However your alternative using an overload is simpler and is perfectly acceptable. It works because the overload for string is declared in the header, so code that calls it knows which function to call.

OTHER TIPS

Overloading is a good approach for many purposes. However, I suspect your original template approach could be made to work too if you add a specialization for const char * as well. That way, you could pass in string literals without it resolving to the numbers version.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top