问题
I have a template class that looks something like this:
template<class T> class C
{
void A();
void B();
// Other stuff
};
template<class T> void C<T>::A() { /* something */ }
template<class T> void C<T>::B() { /* something */ }
What I want is to provide an explicit specialization for only A
while retaining the default for B
and the "other stuff".
What I have tried so far is
class D { };
template<> void C<D>::A() { /*...*/ } // Gives a link error: multiple definition
Every other variant I've attempted fails with parse errors.
What I did:
The original problem was that the explicit specialization was in a header file so it was getting dumped into several object files and messing up the link (Why doesn't the linker notice all the instances of the symbol are the same a just shut up?)
The solution ends up being to move the explicit specialization from the header file to a code file. However to make the other users of the header file not instance the default version, I needed to place a prototype back in the header. Then to get GCC to actually generate the explicit specialization, I needed to place a dummy variable of the correct type in the code file.
回答1:
Alternatively to Martin York's inline solution you could also do in your header file:
class D { };
template<> void C<D>::A(); // Don't implement here!
And supply a .cpp file with the implementation:
template<> void C<D>::A() { /* do code here */ }
So you avoid the multiple definitions by supplying a single one. This is also good to hide implementations for specific Types away from the template header file when publishing the library.
回答2:
Try
template<> inline void c<int>::A() { ... }
// ^^^^^^
As you have defined it in a header file. Each source file that sees it will build an explicit version of it. This is resulting in your linking errors. So jsut declare it as inline.
来源:https://stackoverflow.com/questions/1481677/how-to-provide-a-explicit-specialization-to-only-one-method-in-a-c-template-cl