2017-12-11 2 views
0

컨텍스트 : int, bool 및 문자열 속성을 허용하는 public 메서드가있는 속성 백이 있습니다. 그리고 그들 모두는 스 니펫이 아래에 첨부 된 템플릿 개인 함수를 호출합니다.템플릿 유형 지정 검사가 해당 유형을 올바르게 처리하지 못하는 이유는 무엇입니까?

질문 : 템플리트 전문화를 점검하여 해당 특성을 해당 맵에 추가하려고합니다. 그러나 코드 C2440의 컴파일러 오류는 "문자열을 int로 변환 할 수 없으며"C2440은 "문자열을 bool로 변환 할 수 없습니다." 그게 왜 문제인지 나는 잘 모르겠다.

해결 시도 : 정적 캐스팅을 시도했지만 문자열에서 int (또는 bool!)로 변환 할 수 없기 때문에 캐스팅 할 수없는 오류가있는 것처럼 보입니다.

template <typename T> 
void PropertyBag::Add(const string& name, const T value) 
{ 
    string errorMessage; 
    if (!IsValidPropertyName(name, errorMessage)) 
    { 
     m_pFailureHandler->Handle(errorMessage); 
     return; 
    } 

    if (!IsPropertyNameUnique(name, m_content)) 
    { 
     m_pFailureHandler->Handle("Property '" + name + "' is not unique"); 
     return; 
    } 

    if (is_same<T, int32_t>::value) 
     m_content.intProperties[name] = value; 
    else if (is_same<T, string>::value) 
     m_content.stringProperties[name] = value; 
    else if (is_same<T, bool>::value) 
     m_content.boolProperties[name] = value; 
    else 
     m_pFailureHandler->Handle("Unsupported value type"); 
} 
+1

사용 "만약 당신이이 3 과부하를 만들 제안 형식 검사 (예 : is_same ...)에 대한 일반 "if"대신 "constexpr"(http://en.cppreference.com/w/cpp/language/if#Constexpr_If) –

+0

pre -11 C++, reinterpret_cast <>를 사용할 수 있습니다. 방금 확인한 이후로 안전한 캐스팅이어야합니다. –

답변

2

귀하의 문제는 당신이 당신의 테스트를 수행하는 함수 본문 때까지 기다려야한다는 것입니다, 전체 함수 본문 컴파일 할 수 b에있다, 그것은 실행되지 않을 수 문의 경우의 몸을 제거하지 않습니다.

이 맵 추가에 불과하다 함수 쓰기 :

void add(std::string const & name, bool value) 
{ 
m_content.boolProperties[name] = value; 
} 
// And one for others 
void add(std::string const &, ...) 
{ 
// failure 
} 
1

당신이 사전-11 C++와 함께 붙어있는 경우를, 당신은> < reinterpret_cast 사용할 수 있습니다. 방금 확인한 이후로 안전한 캐스팅이어야합니다.

if (is_same<T, int32_t>::value) 
    m_content.intProperties[name] = *reinterpret_cast<const int32_t*>(&value); 
// etc... 

하지만 적절한 방법은 아닙니다. 타입 시스템이 대신 힘든 작업을하도록해야합니다. m_content 유형에 액세스 할 수 있습니다.

struct Content 
{ 
    void setproperty(const std::string& name, bool b) 
    { 
     boolProperties[name] = b; 
    } 

    void setproperty(const std::string& name, int32_t n) 
    { 
     intProperties[name] = n; 
    } 

    void setproperty(const std::string& name, const std::string& s) 
    { 
     stringProperties[name] = s; 
    } 
}; 

콘텐츠를 변경할 수없는 경우, 사용자가 만들 수있는 무료 기능

void setproperty(Content& content, const std::string& name, bool b) 
    { 
     content.boolProperties[name] = b; 
    } 

    void setproperty(Content& content, const std::string& name, int32_t n) 
    { 
     content.intProperties[name] = n; 
    } 

    void setproperty(Content& content, const std::string& name, const std::string& s) 
    { 
     content.stringProperties[name] = s; 
    } 

귀하의 추가 기능은 다음이된다 :

template <typename T> 
void PropertyBag::Add(const string& name, const T value) 
{ 
    string errorMessage; 
    if (!IsValidPropertyName(name, errorMessage)) 
    { 
     m_pFailureHandler->Handle(errorMessage); 
     return; 
    } 

    if (!IsPropertyNameUnique(name, m_content)) 
    { 
     m_pFailureHandler->Handle("Property '" + name + "' is not unique"); 
     return; 
    } 
    setProperty(m_content, name, value);   
    // or m_content.setProperty(name, value); 
} 
+0

'reintepret_cast'로'value' 주소를 가져 가야합니다. – Phil1970

+0

나쁜. 내가 작성한 모든 버그에 대해 한푼도 –

관련 문제