VC++2010 中的编译器错误(2008 年干净!),“对重载函数的模糊调用”

Posted

技术标签:

【中文标题】VC++2010 中的编译器错误(2008 年干净!),“对重载函数的模糊调用”【英文标题】:Compiler error in VC++2010 (clean in 2008!), "ambiguous call to overloaded function" 【发布时间】:2010-08-25 16:56:51 【问题描述】:

我在 VS2010 中遇到编译错误,而代码在 VS2008 中可以完全编译。

这是我的错误,来自输出窗口,其中包含所有详细信息:

...\elementimpl.h(49): error C2668: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string' : ambiguous call to overloaded function
      with
      [
          _Elem=char,
          _Traits=std::char_traits<char>,
          _Ax=std::allocator<char>
      ]
      c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(700): could be 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(std::basic_string<_Elem,_Traits,_Ax> &&)'
      with
      [
          _Elem=char,
          _Traits=std::char_traits<char>,
          _Ax=std::allocator<char>
      ]
      c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(590): or       'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const _Elem *)'
      with
      [
          _Elem=char,
          _Traits=std::char_traits<char>,
          _Ax=std::allocator<char>
      ]
      while trying to match the argument list '(CXStr)'

这是错误的代码,elementimpl.h(49):

    std::string getAttributeValue(const char* attr)  return getAttribute(CXStr(attr)); 

getAttribute() 返回一个 CXStr(一个 ADT),显然没有 std::string 构造函数接受,所以它需要将 CXStr 转换为合适的东西。

CXStr 可以转换为 std::string 或 char*:

class CXStr

public:
    ...
    CXStr(std::string);
    CXStr(const char* ch);

    const CXStr& operator=(const char*);
    const CXStr& operator=(std::string&);

    operator char*();
    operator std::string(); 
    ...

当我在VS2008中运行调试器时,我可以看到它在getAttribute()之后通过“CXStr::operator std::string()”,然后通过std ::string 复制构造函数,用于创建要由 getAttributeValue() 返回的对象。我希望我的 2010 版本的行为方式相同。

我的问题:

VS2010 有何不同,以及 为什么? 我可以对哪些代码进行更改 修复这个错误?有些事情 工作,但不满意:
    注释掉“CXStr::operator char*()"; 不满意,因为有些 其他代码使用此转换。 显式调用 “getAttribute(...).operator std::string()" at elementimpl.h(49); 不吸引人,因为同样的错误 发生在27个不同的地方,它 似乎必须有更多 集中的方式来解决它。

【问题讨论】:

getAttribute的声明是什么? CXStr getAttribute(const XMLCh* pAttr); 【参考方案1】:

问题是,VS2010 添加了移动构造函数,而你的实现直接落入了这个漏洞。

以前只有一个构造函数,即 const char* 构造函数,它可用于 std::string 构造函数。现在还有移动构造函数。

我真的认为依赖隐式转换的设计是危险的。这就是为什么所有一个参数构造函数都应该是显式的......

我认为您不应该使用隐式运算符,因为它们会导致使用错误的重载。如果您不能这样做,请将当前失败的调用包装到显式转换调用std::string( CXStr( x ).toString() )。使用“非显式”转换运算符可能会隐藏其他错误...。

【讨论】:

【参考方案2】:

你为什么还没有尝试注释掉操作符 std::string() 呢?

您也可以将您的 CXStr 显式转换为 std::string。

但坦率地说,我看不到这个 CXStr 东西的用途。它以服务的方式提供什么(如果有的话)?

【讨论】:

就像我说的,在 VS2008 中内置,"CXStr::operator std::string()" 是选择的转换路径,我想保留这种行为,所以消除该运算符似乎不是-我的选项。 我尝试将 elementimpl.h(49) 更改为 "std::string getAttributeValue(const char* attr) return static_cast<:string>(getAttribute(CXStr(attr))); ”,但编译器抱怨:“...\elementimpl.h(49): error C2440: 'static_cast' : cannot convert from 'CXStr' to 'std::string'[\n]No constructor could take the source type , 或构造函数重载决议不明确” CXStr 的功能远不止我在问题中粘贴的 sn-p。它的主要用途是在与 Xerces-C++ 兼容的字符串之间进行转换(使用 XMLCh* 类型的元素,即 UTF-16)。 事情是这样的……显然你将不得不改变一些东西。我知道没有人喜欢改变,但这是不可避免的,所以要习惯它。既然您因使用隐式转换运算符而受到抨击,您可能会从该经验中吸取教训,并在下次三思而后行。 我在维护模式下工作。这段代码不是我写的。我只是支持它。显然,我将不得不改变一些东西,我认识到这一点。我只是想了解这里发生了什么,并确保我所做的改变是正确的。你的语气不是很有建设性。

以上是关于VC++2010 中的编译器错误(2008 年干净!),“对重载函数的模糊调用”的主要内容,如果未能解决你的问题,请参考以下文章

安装过SQL Server 2008失败,求解。

用VC2010编译Python扩展

问题:工程迁移 VC6->VS2008->VS2010

Visual C++ 2008 和 g++ 的区别

用VS2008如何编译.c,C语言文件?

vc2010的项目迁移到vc2019,解决编译错误问题