c++ - MSVS 2012 "ambiguous call to overloaded function"中的编译器错误

标签 c++ operators constants

我有一个 Item可以携带多种类型数据的类,包括 std::map<Item, Item> . 我定义了 operator[]执行以下操作:如果 Item 不是 V_MAP 类型(V_MAP 是我指定携带类型的枚举的一部分),Item 将其类型更改为 V_MAP。在这个“类型转换”之后,它返回 internalMap [ ItemPassedAsArgument ] .运营商有以下声明:

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

它工作正常,我已经通过各种方式进行了测试。

现在,这需要与其他一些东西集成,首先是 ClassX。

ClassX 有一个 Item(V_MAP) 类型的成员。它需要容纳东西。它(ClassX)还有一个成员方法定义如下:

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

keySmth 在哪里

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

我不允许更改 getSmth() 的定义方法。那个 const 需要留在那里,那个方法应该只检查东西。

如您所见,该方法无法更改任何内容,因此与我的运算符相矛盾。像这样使用时,错误显示 No operator[] matches these operands.Operands are const Item [ const std::string ] . 因此,我重载了 operator[]做几乎相同的事情,除了它改变 Item 类型的部分, 并返回一个常量 Item .这是它的声明:

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

现在由程序员来确保下标运算符现在仅应用于 Item V_MAP 类型的 s。

但现在我得到以下编译器错误:

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)'

问题出在哪里? 谢谢

编辑:这是 std::string 的构造函数:

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

std::string来自 Item :

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;
}

最佳答案

这是模棱两可的原因是你的转换运算符,它可以将 Item 转换成任何东西(至少在这里你应该注意到这是 super 模棱两可的)。

std::string 可以通过复制构造函数或使用 char 指针构造(两者都只有 1 个参数,还有一些构造函数,但这些与此无关)。在这种情况下,编译器不知道他是否应该将 Item 对象转换为 char*std::string 以便构造一个字符串(请注意,当您按值返回时,会创建一个临时字符串)。

我会建议您摆脱那个强制转换操作符,我觉得它很老套,而且我确信这只是该方法会出现的众多问题之一。定义混凝土浇铸。

如果您想保留该运算符,另一种可能性是定义一个 toString() 方法,它比 IMO 中的隐式转换更清晰。

第三种可能性是显式转换您的Item。然后你可以写:

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

关于c++ - MSVS 2012 "ambiguous call to overloaded function"中的编译器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20246950/

相关文章:

c++ - 输入缓冲如何在 C++ 中工作

C++链表简单题

java - If 语句,将一个变量与多个变量进行比较

C - 从 C++ 模拟 'mutable'

c++ - -lglut32 找不到

c++ - (C++) 如何生成一个七位数字,其数字相加等于七的倍数?

c++ - "auto changes meaning in c++11"

java - 大于和小于一个语句

c++ - 在什么意义上 const 只允许对可变成员变量进行原子更改?

c++ - 在指向成员的指针和指向常量成员的指针之间转换