I have structs/class like this:
struct LD { //Login detail
std::string username;
std::string password;
std::string toString() const {
return "Username: " + username
+ " Password: " + password;
}
};
struct UP { //User Profile
std::string name;
std::string email;
ostream& pPrint(ostream& ost) const {
ost << "Name: " << name
<< " Email: " << email;
return ost;
}
std::string toString() const {
return "NULLSTRING";
}
};
I am creating a template pPrint class which will call pPrint function of that class if its present. if not, it will call toString function of that class if its also not available it will print "NO print function"
priority :- 1)pPrint 2)toString 3)simply output "NO print Function"
int main() {
LD ld = { "And", "Ap" };
UP up = { "James Brannd", "jamens@goo.com" };
// this should print "Name: James Email: jamens@goo.com"
std::cout << PPrint <UP> (up) << std::endl;
// this should print "Username: And Password: Ap"
std::cout << PPrint <LD> (ld) << std::endl;
}
now I have created this class as below:
template<typename T>
struct HaspPrintMethod
{
template<typename U, std::ostream&(U::*)(std::ostream&) const> struct SFINAE {};
template<typename U> static char Test(SFINAE<U, &U::pPrint>*);
template<typename U> static int Test(...);
static const bool Has = sizeof(Test<T>(0)) == sizeof(char);
};
template <class T>
class PPrint {
public:
PPrint(T m)
{
CallPrint(m, std::integral_constant<bool, HaspPrintMethod<T>::Has>());
}
void CallPrint(const T& m, std::true_type)
{
std::ostringstream os;
m.pPrint(os);
buf = os.str();
}
void CallPrint(const T& m, std::false_type)
{
buf = m.toString();
}
std::string buf;
};
template <class T>
std::ostream& operator<<(std::ostream &os, pPrint<T> const &m)
{
return os << m.buf;
}
but it's not working refer: Check if a class has a member function of a given signature
new requirement:- Template Class name is PPrint the function we want to detect is 1)pPrint 2)toString 3)if not this to "No func available"
pPrint with this prototype should be detected:
ostream& pPrint(ostream& ost) const;
but the functions in the structs can be like: (which should not get detected)
ostream& PPrint(ostream& ost) const; // case sensitive and same name as class name
ostream& pPrint(ostream& ost); //without const specifier
How to construct Template Class PPrint to do so?