Question about C ++ template functions accepting any type if this type satisfies at least one of the requirements

Since I cannot 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 that accepts any type T if that type has a member function of print1 OR a print2 (not polymorphism)?

+4
source share
2 answers

One approach is to use SFINAE to determine the existence of a function ( Is it possible to write a template to verify the existence of a function ? , SFINAE to check inherited member functions ) and combine knowledge with something like Boost.Enable_if .

+5
source

@UncleBens: I don’t want to edit your message, here is an example code (I hope it is ready for copy / paste), 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 of adding the disable_if parameter to show similarities with the if / else if / else block.

I would love some feedback.

+1
source

Source: https://habr.com/ru/post/1305385/


All Articles