【发布时间】:2011-09-18 02:41:20
【问题描述】:
考虑以下 C++ 代码:
struct B { };
struct A
{
A(int);
A(A&); // missing const is intentional
A(B);
operator B();
};
A f()
{
// return A(1); // compiles fine
return 1; // doesn't compile
}
这在 MSVC++ 2010 上编译得很好(事实上,在 MSVC 上,如果我完全删除 B 它甚至可以工作)。它不在 GCC 4.6.0 上:
conv.cpp: In function ‘A f()’:
conv.cpp:13:9: error: no matching function for call to ‘A::A(A)’
conv.cpp:13:9: note: candidates are:
conv.cpp:6:2: note: A::A(B)
conv.cpp:6:2: note: no known conversion for argument 1 from ‘A’ to ‘B’
conv.cpp:5:2: note: A::A(A&)
conv.cpp:5:2: note: no known conversion for argument 1 from ‘A’ to ‘A&’
conv.cpp:4:2: note: A::A(int)
conv.cpp:4:2: note: no known conversion for argument 1 from ‘A’ to ‘int’
让我感到困惑的是no known conversion for argument 1 from ‘A’ to ‘B’ 的消息。考虑到A::operator B() 的定义非常明确,这怎么可能是真的?
【问题讨论】:
-
我不确定
B与这里有什么关系。您正在将int转换为A,不是吗?所以你故意从复制构造函数中省略了const,所以它不起作用。你预计会发生什么? -
可能无法将 1 转换为
B?错误消息显示for argument [number] 1。 -
@littleadv:如果
B被删除,即使return A(1)也不再起作用。即使在没有 const 复制构造函数的情况下,A::operator B()和A::A(B)的存在也允许从函数返回A。此技巧在 C++ 标准中用于实现std::auto_ptr:参见 ISO/IEC 14882:2003, §20.4.5.2(此处为auto_ptr=A,auto_ptr_ref=B)。 -
@Vlad:我不确定你想说什么。 GCC 成功将
1转换为A,因为第一条错误消息是关于A::A(A),而不是A::A(int)。然而,它无法将A转换为B,尽管A::operator B()和A::A(B)是明确定义的。我试图理解为什么。 -
好吧,@DeadMG 的回答对我来说看起来不错。
标签: c++ gcc copy-constructor implicit-conversion