tags:

views:

138

answers:

2

Since i cant explain this very well, i will start with a small example right away:

template <class T> void Print(const T& t){t.print1();}
template <class T> void Print(const T& t){t.print2();}

This does not compile:
error C2995: 'void Print(const T &)' : function template has already been defined

So, how can i create a template function which takes any type T as long as that type has a print1 memberfunction OR a print2 memberfunction (no polymorphism) ?

+5  A: 

One approach would be to use SFINAE to detect if a function exists ( http://stackoverflow.com/questions/257288/possible-for-c-template-to-check-for-a-functions-existence, http://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions ), and combine the knowledge with something like Boost.Enable_if.

UncleBens
*Just* writing up the examples, but now I'm too lazy. The linked questions have enough information anyway. :)
GMan
+1  A: 

@UncleBens: did not want to edit your post, here is an example of code (hopefully ripe for copy/pasting), put it in your post and comment on this answer so that I can delete it :)

template <class T>
class HasPrint1
{
public:
  struct type
  {
    enum { value = ( sizeof(dummy((T*)0)) == sizeof(yes_t) ) };
  };

  typedef char yes_t;
  struct no_t { yes_t[2] m; };

  template <class C>
  static yes_t dummy(C*, size_t = sizeof(&C::print1));

  static no_t dummy(...);
};

// same for HasPrint2


template <class T>
boost::enable_if< HasPrint1<T> > Print(const T& t) { t.print1(); }

template <class T>
boost::enable_if< HasPrint2<T> > Print(const T& t) { t.print2(); }

template <class T>
boost::disable_if< boost::mpl::or_< HasPrint1<T>, HasPrint2<T> > >
Print(const T& t) { std::cout << t << std::endl; }

I took the liberty to add a disable_if option to show the similarity with a if / else if / else block.

I'd be glad for some reviews.

Matthieu M.
your HasPrint1 template does not work for me, `dummy` and `yes_t` is not declared in `struct type`. so i moved the private part above the public part but i got: `error: 'dummy' declared as function returning an array`
smerlin
Good call, I changed `no_t` into a `struct` containing the array and removed the `private` keyword.
Matthieu M.