Kyle
Kyle

Reputation: 4597

how to specialize templated member functions of non-templated classes?

suppose I have a file alpha.h:

class Alpha {
public:
    template<typename T> void foo();
};

template<> void Alpha::foo<int>() {}
template<> void Alpha::foo<float>() {}

If I include alpha.h in more than one cpp file and compile with GCC 4.4, it complains there are multiple definitions of foo<int> and foo<float> across multiple object files. Makes sense to me, so I change the last two lines to:

template<> extern void Alpha::foo<int>() {}
template<> extern void Alpha::foo<float>() {}

But then GCC says:

explicit template specialization cannot have a storage class

ok... so how am I supposed to do this correctly? I'm worried that C++ doesn't allow what I'm trying to do in the first place, in which case is there a good idiom that will accomplish the same thing?

Upvotes: 5

Views: 3050

Answers (4)

Prashant Singh
Prashant Singh

Reputation: 51

No separate declaration or inline keywork is required. PF below working code.

#include<iostream>

class temp
{
public:
    template <class T>
    T add1(T a, T b)
    {
            return (a + b);
    }
};

template<>
std::string temp::add1<std::string>(std::string aa, std::string bb)
{
    return aa+bb;
}

int main()
{
    temp *tc = new temp();
    std::cout << tc->add1<float>(5.7, 4.5) << std::endl;
    std::cout << tc->add1<std::string>("my ","program") << std::endl;
}

output is :

10.2

my program

Upvotes: -1

AnT stands with Russia
AnT stands with Russia

Reputation: 320719

From the ODR point of view, a fully (explicitly) specialized template is no longer a template, so it is subject to the same ODR principles as a non-template entity of the same kind. (There are some exceptions from that rule, I believe, but it is good enough for our purposes).

In your case, for ODR purposes a fully specialized function template is an ordinary function. So, as an ordinary function it should be declared in the header file and defined in one and only one implementation file.

Upvotes: 4

Edward Strange
Edward Strange

Reputation: 40897

You can forward declare as well as the inline option:

// .h
template<> void Alpha::foo<int>();

//.cpp
template<> void Alpha::foo<int>() {}

Upvotes: 6

Anycorn
Anycorn

Reputation: 51555

use inline keyword

template<> inline void Alpha::foo<int>() {}

alternatively, provide implementation in separate cpp file

Upvotes: 10

Related Questions