如何设计以下类型的模板化课程?

时间:2016-10-08 19:33:16

标签: templates c++11 static-polymorphism

这个问题在接受我的采访时被问到了。我仍在寻找这个问题的解决方案。

  

以下两种类型的函数(两者或一件)可以存在于具体类中:

     
      
  1. ostream& prettyPrint(ostream& ost) const;
    
  2.   
  3. std::string toString() const;
    
  4.         

    我们的目标是设计一个支持两种实现的模板类PrettyPrint

PrettyPrint在我写的优先级中使用具体类的函数:如果两者都存在,则使用第一个,否则使用第二个。

    // ******* given code - start ********

    struct LoginDetails {
        std::string m_username;
        std::string m_password;

        std::string toString() const {
            return "Username: " + m_username
            + " Password: " + m_password;
        }
    };

    struct UserProfile {
        std::string m_name;
        std::string m_email;

        ostream& prettyPrint(ostream& ost) const {
            ost << "Name: " << m_name
            << " Email: " << m_email;
            return ost;
        }

        std::string toString() const {
            return "NULLSTRING";
        }
    };
    // ******* given code - end ********

    // Implement PrettyPrint Class
    template <class T>
    class PrettyPrint {
    public:
        PrettyPrint(){

        }
    };

    int main() {

        LoginDetails ld = { "Android", "Apple" };
        UserProfile  up = { "James Bond", "james@bond.com" };

        // this should print "Name: James Email: james@bond.com"
        std::cout << PrettyPrint <UserProfile> (up) << std::endl;

        // this should print "Username: Android Password: Apple"
        std::cout << PrettyPrint <LoginDetails> (ld) << std::endl;
    }

1 个答案:

答案 0 :(得分:0)

template<typename T>
struct HasPrettyPrintMethod
{
    template<typename U, std::ostream&(U::*)(std::ostream&) const> struct SFINAE {};
    template<typename U> static char Test(SFINAE<U, &U::prettyPrint>*);
    template<typename U> static int Test(...);
    static const bool Has = sizeof(Test<T>(0)) == sizeof(char);
};

template <class T>
class PrettyPrint {
public:
    PrettyPrint(T m)
    {
        CallPrint(m, std::integral_constant<bool, HasPrettyPrintMethod<T>::Has>());
    }
    void CallPrint(const T& m, std::true_type)
    {
        std::ostringstream  os;
        m.prettyPrint(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, PrettyPrint<T> const &m)
{
    return os << m.buf;
}

REF:Check if a class has a member function of a given signature