MSVS 2012中的编译器错误“对重载函数的模糊调用”

时间:2013-11-27 15:49:43

标签: c++ operators const

我有一个Item类,可以携带多种类型的数据,包括std::map<Item, Item>。 我已定义operator[]来执行以下操作:如果Item不是V_MAP类型(V_MAP是我指定所携带类型的枚举的一部分),则Item将其类型更改为V_MAP。在此之后&#34;施放&#34;,它返回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的类型的部分,并返回const Item。这是它的声明:

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

问题出在哪里? 感谢

编辑:这是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;
}

1 个答案:

答案 0 :(得分:3)

这是一个暧昧的原因是由于你的演员操作符,它可以将Item投射到任何东西(至少在这里你应该注意到这是超级暧昧的)。

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

我建议你摆脱那个演员操作员,对我来说看起来非常讨厌,我确信这只是该方法会出现的许多问题之一。定义混凝土模型。

如果你想保留那个运算符,另一种可能性就是定义一个toString()方法,它比隐式转换方法更加清晰。

第三种可能性是明确地施展你的Item。然后你可以写:

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