【问题标题】:Compiler error in MSVS 2012 "ambiguous call to overloaded function"MSVS 2012 中的编译器错误“对重载函数的模糊调用”
【发布时间】:2013-12-13 08:37:33
【问题描述】:

我有一个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;

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

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

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 创建std::string?这就是相关的代码部分。
  • 我已经编辑了问题,你可以在它的末尾找到构造函数
  • 我们不需要std::stringItem,而是Itemstd::string
  • 对不起,读得太快了:P

标签: c++ operators constants


【解决方案1】:

这是模棱两可的原因是由于您的转换运算符,它可以将Item 转换为简单的任何东西(至少在这里您应该注意到这是超级模棱两可的)。

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

我会建议你摆脱那个强制转换操作符,这对我来说看起来很老套,我确信这只是该方法会出现的许多问题之一。定义混凝土铸件。

如果您想保留该运算符,另一种可能性是定义一个 toString() 方法,该方法比 IMO 的隐式转换要干净得多。

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

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

【讨论】:

  • 但是当我测试了Item 的功能时,我写了一个testString(std::string testStr); 并传递了一个Item(V_STR),它工作正常
  • 尝试写std::string foo(itemObj);
  • 哈哈,不错。同样的错误。好吧,我会写一个toString()方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多