Sign in to follow this  

Single member specialization - is this well-formed C++?

This topic is 4811 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

Hi, I tested out of curiosity if the following potentially very handy construct works, and it does, at least on gcc 3.3. But does the Standard agree with gcc? I'm asking because I haven't seen this used anywhere else, despite its usefulness.
template <class T>
struct foo
{
  int bar() { return 0; }
  // lots of stuff I want to have
  // in every template instantation
  // whether specialized or not
};

// Now let's specialize the method bar
// No need to write a full class specialization
// and use inheritance to have lots_of_stuff in
// the specializations too
template <>
int foo<int>::bar() { return 1; }

template <>
int foo<float>::bar() { return 2; }


-Sharlin

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Excuse me, WHY would you want to do this? What's the advantage? I don't get it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Excuse me, WHY would you want to do this? What's the advantage? I don't get it.


If you have to ask that, the answer is: "probably nothing, for you".

That said, here is easy potential for usefulness #1:

Optimizations based on type.

Basic example: standard containers.
Example template class function: "get_all_data" which returns a contiguous array of all the data of the container because you're working with some legacy code, and you really need to.
General solution: create a copy, and return it.
Specialization: std::vector. It allready is contiguous. Just return &(the_container[0]); for that container.

Sure, you're probably doing something wrong if you need to return a contiguous array in the first place and you're not allready using a contiguous container, but this would be an example. Prehaps you're converting the code in stages. I dunno.

Share this post


Link to post
Share on other sites
A motivating example: Let's say I have a templated functor class which offers a common interface for a set of various function types:


template <typename Func>
class functor
{
public:
functor(Func *f) : f(f) { }
void operator () (const vector<variant> &);
operator bool () { return f; }
/* other generic stuff, operator== etc */
private:
Func *f;
};



Now, how to go about implementing the operator() ? As Func can be for example float (), void (float), or, say, int (float, int, std::vector, int (*)(double, char)), it is clear that we need to specialize operator() for each of these types. So, we do just that:


template <>
functor<void ()>::operator () (const vector<variant> &v)
{
f();
}

template <>
functor<void (float)>::operator () (const vector<variant> &v)
{
f(float(v[0]));
}

/* and so on */



This is actually almost straight from my little scripting language's compiler/vm, where there's a set of built-in functions (such as sin, pow, and like) which require a common interface when called from the virtual machine.

Share this post


Link to post
Share on other sites
Darn. Alas, it seems that partial specialization of methods doesn't work without specializing the whole class at the same time. I wonder why.

For example, the following fails to compile on gcc 3.4:

template <class T>
struct foo { void bar(); };

template <class T>
void foo<T *>::bar() { }

gcc emits the following error messages:
foo.cpp:15: error: no `void foo<T*>::bar()' member function declared in class `foo<T*>'
foo.cpp:15: error: template definition of non-template `void foo<T*>::bar()'

Adding an explicit specialization of struct foo<T *> makes the program compile.

Share this post


Link to post
Share on other sites

This topic is 4811 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this