question about c++ template functions taking any type as long that type meets at least one of the requirements
Since i cant explain this very well, i will start with a开发者_Python百科 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) ?
One approach would be to use SFINAE to detect if a function exists ( Is it possible to write a template to check for a function's existence?, SFINAE to check for inherited member functions ), and combine the knowledge with something like Boost.Enable_if.
@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.
精彩评论