• Advertisement
Sign in to follow this  

Partial template specialization - Modern C++ Design

This topic is 4733 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

In Modern C++ Design it gives one of the drawbacks of templates in section 1.4:
Quote:
Specialization of member functions does not scale. You can specialize any member function of a template with one template parameter, but you cannot specialize individual member functions for templates with multiple template parameters. For example:
template <class T> class Widget {
    void Fun () { /* generic implementation */ }
};

// OK: specialization of a member function of Widget
template <> Widget<char>::Fun () {
    // special implementation
}

template <class T, class U> class Gadget {
    void Fun () { /* generic impementation */ }
};

// Error! Cannot partially specialize a member class of Gadget
template <class U> void Gadget<char, U>::Fun () {
    // special implementation
};

I have not used template specialization very much, and I don't understand his point or his example. Is he saying it is not possible to use template specialization in this way, or is he saying it doens't solve any of the design problems he's trying to solve? Clarification would be appreciated.

Share this post


Link to post
Share on other sites
Advertisement
Your example of a 'specialization if a member of gadget' is not a specialization of a member of gadget. A member function specialization would look something like


class Gadget
{
template <typename A, typename B> void Func(...);

//partial specialization
template <typename A> void Func<A,C>(...);
};


It's not legal C++, though I'd argue that it probably should be.

Share this post


Link to post
Share on other sites
He's saying that it just isn't possible, unfortunately. I ran into this exact problem (I'd call it a defect) in this thread.

Deyja: You can do this using ordinary function overloading:

template <typename T, typename U>
void foo(T t, U u) { }

template <typename T>
void foo(T t, int i) { } // A "specialization" of foo


Unfortunately this doesn't work with non-type parameters, so in that sense it is indeed a defect.

Share this post


Link to post
Share on other sites
First, check the erratum for the book [wink]

// Error! Cannot partially specialize a member class function of Gadget
template <class U> void Gadget<char, U>::Fun () {
// special implementation
};


And he is saying it is not possible.

Deyja - There are two ways to defined a class specialization.

First, you can rewrite the entire, specialized, version of the class:

template <class T> class Widget {
void Fun () { /* generic implementation */ }
};

template <> class Widget<char>
{
void Fun () { /* special implementation */ }
};


But you can also, as the code Russel posted (from the book, by the way, he's not making it up), provide the generic implementation of the class and just specialize the functions that need to - instead of rewriting the entire class. (IIRC, you can't however mix the two approaches.)

The Widget example he posted illustrates that.

Now, while the familiar approach to specialization allows you to write partially specialized classes:


template <class T, class U> class Gadget {
void Fun () { /* generic implementation */ }
};

template <class U> class Gadget<char,U>
{
void Fun () { /* special implementation */ }
};


You cannot use the 'specialized member function' approach with partial specialization - it just does not work. This is what the Gadget example is intended to show.

Share this post


Link to post
Share on other sites
Gadget<char, Foo>::Fun() could mean either the generic or the specialized version, as opposed to Widget<char>::Fun() which clearly means the specialized version. So the reason why this technique does not scale for member functions is ambiguity. However, you can partially specialize classes, but you have to implement the whole class. Is this all correct?

Maybe I need to reread the section on templates in The C++ Programming Language [smile]

Share this post


Link to post
Share on other sites
Quote:
Gadget<char, Foo>::Fun()


But that isn't a specialization of a member template function - it's a non-template member function for a specialization of the class. I suspect one of the reasons it was left out is because it is the ugliest syntax I've ever seen.
You can't partially specialize member function templates (You can use overloads, but they follow slightly different matching rules), and you can't declare member functions for partially specialized classes without declaring the entire class. Two entirely different restrictions.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement