C++模板类推导

#include "stdafx.h"

#include <iostream>
#include <memory>
#include <vector>
#include <map>
#include <queue>
#include <string>
using namespace std;

/// \class LimitedCast
/// 
/// \brief LimitedCast is used to cast string to different type of values.
///        Only limited number of types are supported by LimitedCast, 
///        and all the supported types are defined in header file: 
///        mcsf_limited_type_defs.h
template<typename T>
class LimitedCast
{
public:
    typedef T Type;

    LimitedCast(void){};
    ~LimitedCast(void){};

    // \brief cast string to type value
    Type ToType(const std::string &) const
    {
        return Type tTemp;
    };

    // \brief cast type value to string
    std::string ToString(const Type &) const
    {
        return "";
    };
};

//特化模板类
template<typename T>
class LimitedCast<std::vector<T>>
{
public:
    typedef std::vector<T> Type;

    LimitedCast(void){};
    ~LimitedCast(void){};

    // \brief cast string to type value
    Type ToType(const std::string &) const
    {
        return Type tTemp;
    };

    // \brief cast type value to string
    std::string ToString(const Type &) const
    {
        return "";
    };
};


template<>
class LimitedCast<int>
{
public:
    LimitedCast(void){};
    ~LimitedCast(void){};

    // \brief cast string to type value
    int ToType(const std::string &) const
    {
        int i;
        return i;
    };

    // \brief cast type value to string
    std::string ToString(const int &) const
    {
        return "";
    };
};

template<>
class LimitedCast<float>
{
public:
    LimitedCast(void){};
    ~LimitedCast(void){};

    // \brief cast string to type value
    float ToType(const std::string &) const
    {
        float i;
        return i;
    };

    // \brief cast type value to string
    std::string ToString(const float &) const
    {
        return "";
    };
};

template<>
class LimitedCast<double>
{
public:
    LimitedCast(void){};
    ~LimitedCast(void){};

    // \brief cast string to type value
    double ToType(const std::string &) const
    {
        double i;
        return i;
    };

    // \brief cast type value to string
    std::string ToString(const double &) const
    {
        return "";
    };
};

/// \class MapAssign
///
/// \brief MapAssign is used to insert a series of 
///        key-value pair into a map.
///        it will help to statically initialize a 
///        constant map.
template <typename K, typename V>
class MapAssign
{
public:
    typedef std::map<K, V>   Map;
    typedef std::pair<K, V>  Pair;

    typedef std::deque<Pair> Deque;

    MapAssign(void)
        try : m_qPairs()
    {
    }
    catch (...)
    {
        throw std::exception();

    }

    ~MapAssign(void)
    {
    }

    /// \brief overloading of operator ().
    ///        it enables you to use MapAssign in this 
    ///        style: 
    ///        MapAssign<K, V>()(key1, value1)(key2, value2);
    /// 
    /// \param[in] kKey   key of a single map element.
    /// \param[in] kValue value of a single map element.
    /// 
    /// \return reference of current MapAssign object.
    MapAssign& operator()(const K &kKey, const V &kValue)
    {
        try
        {
            m_qPairs.push_back(Pair(kKey, kValue));

            return *this;
        }
        catch (...)
        {
            throw std::exception();
        }
    }

    /// \brief overloading of operator std::map<K, V>
    /// 
    /// \return an object of std::map<K, V>.
    operator Map() const
    {
        try
        {
            return Map(m_qPairs.begin(), m_qPairs.end());
        }
        catch (...)
        {
            throw std::exception();
        }
    }

private:
    Deque m_qPairs;
};

/// \class LimitedAssignBase
/// 
/// \brief Base class of Assigner.
class LimitedAssignBase
{
public:
    typedef std::shared_ptr<LimitedAssignBase> Ptr;

    LimitedAssignBase(void);

    virtual ~LimitedAssignBase(void) = 0;

    /// \brief get the type of the value to be assigned.
    /// 
    /// \return type of the value.
    virtual const std::string &WhatType(void) const = 0;

    /// \brief check the type of the Assigner.
    /// 
    /// \param[in] sLit literal type to be check.
    ///                 literal type is not the actual 
    ///                 type id of one type, instead it
    ///                 represents a compiler-independent
    ///                 type. the supported literal types
    ///                 are defined in mcsf_limited_type_defs.h
    /// 
    /// \return true,  if the assigner matches the literal type;
           false, if no match happens.
    bool IsLiteralType(const std::string &) const;
private:
    //DISALLOW_COPY_AND_ASSIGN(LimitedAssignBase);
};

inline LimitedAssignBase::LimitedAssignBase(void)
{
}

inline LimitedAssignBase::~LimitedAssignBase(void)
{
}

/// \class LimitedAssignCMVBase
/// 
/// \brief Base template class used to set member 
///        variables of one class.
template<class I>
class LimitedAssignCMVBase : 
    public LimitedAssignBase
{
public:
    typedef std::shared_ptr<LimitedAssignCMVBase> Ptr;
    typedef I                                     Interface;

    LimitedAssignCMVBase(void);

    virtual ~LimitedAssignCMVBase(void) = 0;

    /// \brief set member variable value of the class
    ///        from a string.
    /// 
    /// \param[in] sSrc   value in string.
    /// \param[in] piThis pointer to the object of the 
    ///                   class.
    /// 
    /// \return true,  if succeed to set the class member
    ///                variable from the string;
    ///         false, if fail to set the value.
    virtual bool FromString(const std::string &, I *) = 0;

    /// \brief convert member variable value of the class
    ///        into a string.
    /// 
    /// \param[in] kiThis reference to the object of the 
    ///                   class.
    /// \param[in] psDes  pointer to string to receive 
    ///                   the converted value.
    /// 
    /// \return true,  if succeed to convert the class member
    ///                variable into the string;
    ///         false, if fail to convert the value.
    virtual bool ToString(const I &, std::string *) const = 0;
private:
    //DISALLOW_COPY_AND_ASSIGN(LimitedAssignCMVBase);
};

template<class I>
inline LimitedAssignCMVBase<I>::LimitedAssignCMVBase(void)
    : LimitedAssignBase()
{
}

template<class I>
inline LimitedAssignCMVBase<I>::~LimitedAssignCMVBase(void)
{
}

/// \class LimitedAssignCMV
/// 
/// \brief LimitedAssignCMV is used to set member 
///        variables of one class.
template<class I, class C, typename T>
class LimitedAssignCMV :
    public LimitedAssignCMVBase<I>
{
public:
    typedef std::shared_ptr<LimitedAssignCMV>           Ptr;
    typedef typename LimitedAssignCMVBase<I>::Interface Interface;
    typedef C                                           Class;
    typedef T                                           Type;

    /// \brief construct LimitedAssignCMV with pointer
    ///        to class member.
    /// 
    /// \param[in] tToAssign class member pointer.
    ///                      template parameter C and T 
    ///                      could be deduced from it.
    LimitedAssignCMV(Type Class::*tToAssign)
        try : LimitedAssignCMVBase<Interface>()
        , m_tToAssign(reinterpret_cast<Type Interface::*>(tToAssign))
        , m_tLmtCast()
    {
    }
    catch (...)
    {
        /// \todo rethrow exception here
    }

    virtual ~LimitedAssignCMV(void)
    {
    }

    /// \brief set member variable value of the class
    ///        from a string.
    /// 
    /// \param[in] sSrc   value in string.
    /// \param[in] piThis pointer to the object of the 
    ///                   class.
    /// 
    /// \return true,  if succeed to set the class member
    ///                variable from the string;
    ///         false, if fail to set the value.
    virtual bool FromString(const std::string &sSrc, Interface *piThis)
    {
        if (nullptr == piThis)
        {
            return false;
        }
        try
        {
            (piThis->*m_tToAssign) = m_tLmtCast.ToType(sSrc);

            return true;
        }
        catch (...)
        {
            return false;
        }
    }

    /// \brief convert member variable value of the class
    ///        into a string.
    /// 
    /// \param[in] kiThis reference to the object of the 
    ///                   class.
    /// \param[in] psDes  pointer to string to receive 
    ///                   the converted value.
    /// 
    /// \return true,  if succeed to convert the class member
    ///                variable into the string;
    ///         false, if fail to convert the value.
    virtual bool ToString(const Interface &kiThis, std::string *psDes) const
    {
        if (nullptr == psDes)
        {
            return false;
        }
        try
        {
            *psDes = m_tLmtCast.ToString(kiThis.*m_tToAssign);

            return true;
        }
        catch (...)
        {
            return false;
        }
    }

    /// \brief get the type of the value to be assigned.
    /// 
    /// \return type of the value.
    virtual const std::string &WhatType(void) const
    {
        static const std::string sTypeAssgn(typeid(Type).name());
        return sTypeAssgn;
    }

private:
    //DISALLOW_COPY_AND_ASSIGN(LimitedAssignCMV);

    Type Interface::* m_tToAssign;
    LimitedCast<Type> m_tLmtCast;
};

/// \brief create LimitedAssignCMV object with class member pointer.
/// 
/// \param[in] tToAssign class member pointer.
/// 
/// \return smart pointer of created LimitedAssignCMV object.
///T相当于是类型的名字如int
template<class I, class C, typename T>
typename LimitedAssignCMV<I, C, T>::Ptr NewLimitedAssign(T C::*tToAssign)
{
    try
    {
        return typename LimitedAssignCMV<I, C, T>::Ptr(
            new LimitedAssignCMV<I, C, T>(tToAssign));
    }
    catch (...)
    {
        return typename LimitedAssignCMV<I, C, T>::Ptr();
    }
}

class IClassAtt
{
public:
    typedef std::map<std::string, 
         LimitedAssignCMVBase<IClassAtt>::Ptr> 
        FunctorAttributeMap;

    typedef MapAssign< std::string, 
         LimitedAssignCMVBase<IClassAtt>::Ptr> 
        FunctorAttributeMapAssign;
public:
    int m_iValue;
    float m_fValue;
    double m_dValue;
};

int _tmain(int argc, _TCHAR* argv[])
{
    IClassAtt::FunctorAttributeMap mapAttrbt;
    
    LimitedAssignCMVBase<IClassAtt>::Ptr ptrTemp = NewLimitedAssign<IClassAtt>( &IClassAtt::m_iValue);
    LimitedAssignCMVBase<IClassAtt>::Ptr ptrTemp1 = NewLimitedAssign<IClassAtt>( &IClassAtt::m_fValue);
    LimitedAssignCMVBase<IClassAtt>::Ptr ptrTemp2 = NewLimitedAssign<IClassAtt>( &IClassAtt::m_dValue);
    LimitedAssignCMVBase<IClassAtt>::Ptr ptrTemp3 = LimitedAssignCMV<IClassAtt,IClassAtt,int>::Ptr(
        new LimitedAssignCMV<IClassAtt,IClassAtt,int>(&IClassAtt::m_iValue));

    mapAttrbt[std::string("m_iValue")] = ptrTemp;
    mapAttrbt[std::string("m_fValue")] = ptrTemp1;
    mapAttrbt[std::string("m_dValue")] = ptrTemp3;

    IClassAtt::FunctorAttributeMap mapAttrbt2 =
         IClassAtt::FunctorAttributeMapAssign()(std::string("m_iValue"),
                              NewLimitedAssign<IClassAtt>( &IClassAtt::m_iValue)); 
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值