2013-04-07 3 views
1

나는 약간의 문제가있어, 해결하고 싶습니다.경고 4244 (데이터 손실 가능성 있음) 템플릿 클래스에서 - Visual Studio 2010

클래스 템플릿을 사용하여 데이터 형식을 typeid()로 검사하여 올바른 방식으로 처리합니다.


template <typename _Ty_Id, 
      typename _Ty_Value> 
    class Attribute : public AttributeBase<_Ty_Id> 
    { 
    public: 
     Attribute() : 
     AttributeBase(_Ty_Id()), 
     m_tyValue(_Ty_Value()) 
     { 
     } 

     Attribute(_Ty_Id tyId, _Ty_Value tyValue) : 
     AttributeBase(tyId), 
     m_tyValue(tyValue) 
     { 
     } 

     virtual ~Attribute() {}; 

     virtual _Ty_Id getId() const {return m_tyId;} 
     virtual _Ty_Value getValue() const {return m_tyValue;} 

     virtual void toXml(iolib::Xml& xmlFile) 
     { 
     std::list<std::string> listXmlData; 
     std::string strTag; 

     if(typeid(m_tyId) == typeid(std::string)) 
     { 
      strTag = m_tyId; 
     } 
     else 
     { 
      strTag = core::Stringfunc::format(strTag, m_tyId, 0, 0); 
     } 

     listXmlData.push_back(strTag); 
     listXmlData.push_back("entrytype"); 
     listXmlData.push_back(m_strEntryType); 
     listXmlData.push_back("datatype"); 
     listXmlData.push_back(m_strDataType); 

     std::string strValue; 
     if(typeid(m_tyValue) == typeid(std::string)) 
     { 
      #pragma warning(disable : 4244) 
      strValue = m_tyValue; 
      #pragma warning(default : 4244) 
     } 
     else if((typeid(m_tyValue) == typeid(float)) || 
       (typeid(m_tyValue) == typeid(double))) 
     { 
      strValue = core::Stringfunc::format(strValue, m_tyValue, 0, 3); 
     } 
     else 
     { 
      strValue = core::Stringfunc::format(strValue, m_tyValue, 0, 0); 
     } 

     listXmlData.push_back(strValue); 
     listXmlData.push_back("/" + strTag); 

     xmlFile.addElement(listXmlData); 
     } 


    private: 
     _Ty_Value m_tyValue; 
    } 

템플릿 인수는 실수 값이며, 다른 지점의 경우에 처리됩니다. 그러나 VS 2010에서는 float에서 std :: string으로의 암시 적 캐스트가 올바르게 작동하지 않을 수도 있다는 경고 # 4244가 표시됩니다.

지금까지 나는 경고가 표시되지 않도록 설정했으며 모든 것이 정상적으로 작동합니다. 그러나 물론 VS2012에서만 작동하며 다른 목표를 가진 코드를 사용하려고합니다.

경고를 방지하는 더 똑똑한 방법을 아는 사람이 있습니까?


EDIT 그래서, 지금은 클래스의 주요 부분을 게시했다.

문제는 다음과 같은 메서드 내에서 발생합니다. toXml (iolib :: Xml & xmlFile) with my xml 클래스에 대한 참조가 허용됩니다. 사용 된 유형 (m_tyValue)은 속성 <> 클래스의 구성원입니다.

템플릿 인수는 다음과 같습니다. m_tyId의 경우 std :: string이고 m_tyValue의 경우 float입니다. 또는 _와 당신이 __ (이중 밑줄)로 시작하는 이름을 사용하지 말아야하고 대문자 :

안부, 해안

+0

RTTI를 사용하지 마십시오. 가능한 한 피해야합니다. 당신의 목표는 무엇입니까? –

+0

음 ... RTTI를 사용하여 유형을 확인하는 것이 좋은 방법이라고 생각했습니다. xml 파일에 값을 쓰고 싶습니다. 따라서 어떤 경우에도 문자열이어야합니다. 템플리트 인수가 부동 또는 정수 유형일 때, 형식 메소드를 사용하여 작업을 수행합니다. 어쩌면 문자열도 처리해야합니다.이 경우에는 아무 것도하지 마십시오. – Coastcrawler

+0

글쎄, 이것에 대해서는 100 % 확신 할 수 없지만, 이것에 의존하는 것은 결코 좋은 방법이 아닙니다. 그것은 매우 모호해질 수 있습니다.나는 당신이 그것을 포기하는 것을 원하지 않지만, 기능성을 위해서, 당신은 당신의 제안을 왜 시도하지 않습니까? 아마 더 나은 것 같습니다!? –

답변

0

참고. C++ Std의 "구현을 위해"[global.names]에 예약되었습니다.

다른 유형 (컴파일 타임에 유형을 알고있는 곳)에 따라 다른 동작을 사용하려면 클래스의 (부분적인) 특수화를 사용할 수 있습니다 템플릿 :

template < typename Ty_Id > 
struct toXmlHelper 
{}; // provide no default implementation 

template < > 
struct toXmlHelper <double> // implementation in case Ty_Id == double 
{ 
    void toXml() { /*...*/ } 
}; 

template < > 
struct toXmlHelper <std::string> // implementation in case Ty_Id == std::string 
{ 
    void toXml() { /*...*/ } 
}; 

코드 중복성을 줄이기위한 기술을 추가 할 수 있습니다. 당신이 m_tyId의 유형을 알다시피, 런타임 형식 정보를 사용하는 이유가

template < typename Ty_Id, 
      typename Ty_Value> 
class Attribute : public AttributeBase<_Ty_Id> 
{ 
public: 
    /* ... */ 
    virtual void toXml(iolib::Xml& xmlFile) 
    { 
     std::list<std::string> listXmlData; 
     std::string strTag; 
     /* ... */ 
     toXmlHelper(m_tyId); 
    } 
private: 
    void toXmlHelper(double); 
    void toXmlHelper(std::string const&); 
} 

없습니다 :

또 다른 방법은 오버로드 메커니즘을 사용하는 것입니다. 클래스 템플릿의 모든 인스턴스화에 대해 컴파일 된 코드 (각 if-clase에 있음)는 플로트를 문자열에 할당하는 것처럼 의미가 없더라도 나타납니다.

+0

예, 부분 전문화는 ... 그것에 대해 생각하지 않았습니다. 샘플을 가져 주셔서 감사합니다. 시도해 보겠습니다. 작동하는지 알려줍니다. 지금까지, 감사합니다 :) – Coastcrawler