tags:

views:

53

answers:

3

I have a template method that is designed to work with a specific set of classes. Since I have no real need for runtime polymorphism, I've decided to not use pointers to the parent class, but rather will have the compiler put everything together for me.

I want to either restrict the type that can be passed to the template, or make GCC issue sensible errors when an incorrect type is passed.

Is this possible?

+1  A: 

Yes. It is possible using a number of different techniques depending on the specific needs of the day. There's boost::enable_if. There's MPL and static_assert...(use BOOST_STATIC_ASSERT if you're not using a C++0x compiler). There's Boost.Concepts.

Yes. It is possible.

Noah Roberts
A: 

On the other hand, you can also NOT use a template.

Let's say you'd like the method to operate only on Car and Dog. Obviously the two are completely unrelated... but they can still move.

// move.h
#include <boost/variant.hpp>

class Car;
class Dog;

typedef boost::variant<Car*,Dog*> move_type;

void move(move_type m);


// move.cpp
#include <boost/apply_visitor.hpp>

#include "car.h"
#include "dog.h"
#include "move.h"

struct Mover: boost::static_visitor<>
{
  void operator()(Car* c) const { c->advance(); }
  void operator()(Dog* d) const { d->run(); }
};

void move(move_type m)
{
  boost::apply_visitor(Mover(), m);
}

And that's even better than a typical template, because the implementation is in the source file :)

Matthieu M.
A: 

You can do something like what Matthieu said, write out separate functions for each type you support (it can still call a template function in the backend), or use dynamic polymorphism and inheritance. Those should be the only kinds of options you should consider to do what you want to do.

However, the question you're asking leads me to believe that's a misunderstanding of templates and static polymorphism. A function/class template imposes restriction on the types that it can work with through the actual code being generated. The public interface that's used in such functions/classes are what define the constraints on the types that can be accepted. There is no need to superfluously impose additional constraints over that. Why would you want to restrict the types a class/function template can support more than the restrictions placed already?

Let's say you write a function template which can only work on types that implement a public interface which consists of a life accessor, a kill function, and an eat function (basically any living organism). That's the constraint it places: you don't need to limit the flexibility by reducing the number of types that will work with the function template beyond that or define any specific organism types that will work that way. The template already requires this living organism-type interface to be implemented.