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 年干净!),“对重载函数的模糊调用”的主要内容,如果未能解决你的问题,请参考以下文章