2013-11-27 6 views
0

std::map<Item, Item>을 비롯한 여러 유형의 데이터를 전달할 수있는 Item 클래스가 있습니다. operator[]에 다음을 수행하도록 정의했습니다. 항목의 유형이 V_MAP이 아닌 경우 (V_MAP은 전달 된 유형을 지정하는 열거 형의 일부 임) 항목의 유형이 V_MAP으로 변경됩니다. 이 "캐스트"후 internalMap [ ItemPassedAsArgument ]을 반환합니다. 운영자는 다음 선언문을 사용합니다.MSVS 2012의 컴파일러 오류 "오버로드 된 함수에 대한 모호한 호출"

Item& operator[] (const Item& itemArg); 

잘 작동하며, 여러 가지 방법으로 테스트했습니다.

이제 다른 것들과 통합해야하는데, 그 중 첫 번째 것은 ClassX입니다.

ClassX에는 Item (V_MAP) 멤버의 멤버가 있습니다. 물건을 가지고 있어야합니다. 다음과 같이 (ClassX)도 정의 된 멤버 메소드를 가지고

std::string ClassX::getSmth() const { 
    return item[keySmth]; 
} 

을 keySmth 내가 getSmth() METHOD OF 정의를 변경하도록 허용하고 있지 않다

const std::string ClassX::keySmth ("blablabla"); 

이다. 그 const는 그곳에 머무를 필요가 있습니다. 그 방법은 사물만을 검사해야합니다.

보시다시피,이 메서드는 아무 것도 변경할 수 없으므로 내 연산자와 모순됩니다. 이와 같이 사용하면 오류는 No operator[] matches these operands.Operands are const Item [ const std::string ]입니다. 따라서 operator[]을 오버로드하여 Item의 형식을 변경하는 부분을 제외하고 거의 동일한 작업을 수행하고 Item이라는 const를 반환합니다.

const Item& operator[] (const Item& itemArg) const; 

그것은 첨자 연산자 지금 형 V_MAP의 Item들에만 적용되도록하기 위해 프로그래머까지 지금이 그것의 선언입니다.

하지만 지금은 다음과 같은 컴파일러 오류 얻을 :

error C2668: 'std::basic_string<_Elem,_Traits,_Alloc>::basic_string' : ambiguous call to overloaded function 

     with 
     [ 
      _Elem=char, 
      _Traits=std::char_traits<char>, 
      _Alloc=std::allocator<char> 
     ] 

     c:\program files (x86)\microsoft visual studio 11.0\vc\include\xstring(896): could be 'std::basic_string<_Elem,_Traits,_Alloc>::basic_string(std::basic_string<_Elem,_Traits,_Alloc> &&) throw()' 

     with 
     [ 
      _Elem=char, 
      _Traits=std::char_traits<char>, 
      _Alloc=std::allocator<char> 
     ] 
     c:\program files (x86)\microsoft visual studio 11.0\vc\include\xstring(789): or  'std::basic_string<_Elem,_Traits,_Alloc>::basic_string(const _Elem *)' 

     with 
     [ 
      _Elem=char, 
      _Traits=std::char_traits<char>, 
      _Alloc=std::allocator<char> 
     ] 

     while trying to match the argument list '(const Item)' 

문제가 있습니까? 감사

편집 :

Item(const std::string str_value) { 
    m_data = new Data<std::string> (str_value); 
    m_type = V_STR; 
} 

std::stringItem에서 :이 표준 : : 문자열의 생성자 인해 캐스트 운영자에

template<typename T> 
operator T() const { 
    //Check 
    if (this->m_data == nullptr) 
     return NULL; 
    // dynamic_cast m_data to point to "an Item of type T" 
    Data<T>* temp_data = dynamic_cast<Data<T>* > (m_data); 
    return temp_data->m_dataOfAnyType; 
} 
+2

'Item'에서'std :: string'을 어떻게 만듭니 까? Revelant 코드 부분입니다. – Paranaix

+0

질문을 편집 했으므로 끝에있는 생성자를 찾을 수 있습니다 – Hame

+0

'Item'에는'std :: string '이 필요하지만'std :: string'에는'Item'이 필요 없습니다 – Paranaix

답변

3

이 ambigious입니다 이유 인 Item을 단순히 무엇이든 주조 할 수 있습니다 (atleast는 여기가 너무 모호하다는 것을 알아야합니다).

std::string은 복사 생성자 또는 char 포인터를 통해 생성 될 수 있습니다 (둘 다 매개 변수가 하나 뿐이며 더 많은 생성자가 있지만 이것과 관련이 없습니다). 이 경우 컴파일러는 Item 개체를 char* 또는 std::string으로 캐스팅하여 문자열을 구성해야하는지 여부를 알지 못합니다. 값으로 반환하면 임시가 만들어집니다.

나는 캐스팅 오퍼레이터를 없애고, 나에게 너무 해킹되어 보이고, 이것이 그 방법으로 발생할 많은 문제 중 하나 일뿐입니다. 구체적인 캐스트를 정의하십시오.

해당 연산자를 유지하려는 경우 암시 적 주조보다 훨씬 더 깨끗한 방법 인 toString()을 IMO로 정의하는 것이 좋습니다.

세 번째 가능성은 명시 적으로 사용자의 Item을 전송하는 것입니다. 그러면 다음과 같이 쓸 수 있습니다 :

return (std::string) item; 
// or 
return (char*) item; 
+0

그러나'Item'의 기능을 테스트했을 때'Item (V_STR)'을 전달한'testString (std :: string testStr);을 작성했는데 제대로 작동합니다. – Hame

+0

' std :: string foo (itemObj); ' – Paranaix

+0

하하, 멋지다. 같은 오류. 좋아, 나는'toString()'메소드를 작성할 것이다. – Hame

관련 문제