C++0x 错误:使用 std::shared_ptr 重载函数到 const 参数不明确
假设我有两个不相关类A
和B
。我还有一个使用 boost::shared_ptr
的 Bla
类,如下所示:
class Bla {
public:
void foo(boost::shared_ptr<const A>);
void foo(boost::shared_ptr<const B>);
}
注意 const。这是这个问题的原始版本所缺少的重要部分。这可以编译,并且以下代码可以工作:
Bla bla;
boost::shared_ptr<A> a;
bla.foo(a);
但是,如果我在上面的示例中从使用 boost::shared_ptr
切换到使用 std::shared_ptr
,则会出现编译错误那就是:
"error: call of overloaded 'foo(std::shared_ptr<A>)' is ambiguous
note: candidates are: void foo(std::shared_ptr<const A>)
void foo(std::shared_ptr<const B>)
你能帮我弄清楚为什么编译器无法弄清楚在 std::shared_ptr 情况下使用哪个函数,而在 boost::shared_ptr 情况下可以吗?我使用的是 Ubuntu 11.04 软件包存储库中的默认 GCC 和 Boost 版本,目前是 GCC 4.5.2 和 Boost 1.42.0。
以下是您可以尝试编译的完整代码:
#include <boost/shared_ptr.hpp>
using boost::shared_ptr;
// #include <memory>
// using std::shared_ptr;
class A {};
class B {};
class Bla {
public:
void foo(shared_ptr<const A>) {}
void foo(shared_ptr<const B>) {}
};
int main() {
Bla bla;
shared_ptr<A> a;
bla.foo(a);
return 0;
}
顺便说一句,这个问题促使我提出这个问题关于我是否应该使用std::shared_ptr
;-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
shared_ptr
有一个模板单参数构造函数,这里考虑将其用于转换。这就是允许在需要shared_ptr
时提供实际参数shared_ptr
的原因。由于
shared_ptr
和shared_ptr
都有这种隐式转换,因此它是不明确的。至少在 C++0x 中,标准要求
shared_ptr
使用一些 SFINAE 技巧来确保模板构造函数仅匹配实际可以转换的类型。签名为(请参阅
[util.smartptr.shared.const]
部分):可能该库尚未更新以符合该要求。您可以尝试更新版本的 libc++。
Boost 不起作用,因为它缺少这个要求。
这是一个更简单的测试用例: http://ideone.com/v4boA (此测试用例在符合要求的编译器上将失败,如果编译成功,则意味着原始情况将被错误地报告为不明确。)
VC++ 2010 正确(对于
std::shared_ptr
)。shared_ptr
has a template single-argument constructor, which is considered for the conversion here. That's what allows an actual parametershared_ptr<Derived>
to be supplied where ashared_ptr<Base>
is needed.Since both
shared_ptr<const A>
andshared_ptr<const B>
have this implicit conversion, it's ambiguous.At least in C++0x, the standard requires that
shared_ptr
use some SFINAE tricks to make sure that the template constructor only matches types that actually can be converted.The signature is (see section
[util.smartptr.shared.const]
):Possibly the library hasn't yet been updated to comply with that requirement. You might try a newer version of libc++.
Boost won't work, because it's missing that requirement.
Here's a simpler test case: http://ideone.com/v4boA (This test case will fail on a conforming compiler, if it compiles successfully, it means the original case will be incorrectly reported as ambiguous.)
VC++ 2010 gets it right (for
std::shared_ptr
).以下代码可以在 GCC 4.5 和 Visual Studio 10 中正常编译。如果您说它无法在 GCC 4.5.2 中编译,那么它听起来像是您应该报告的编译器错误(但请确保它确实发生,更有可能是您创建的)某种打字错误)。
The following compiles fine with GCC 4.5 and Visual Studio 10. If you say it doesn't compile in GCC 4.5.2 then it sounds like a compiler bug which you should report (but make sure that it really happens it's more likely that you made some sort of typo).
您可以使用
std::static_pointer_cast
添加const
限定:You can use
std::static_pointer_cast
to add theconst
qualification:http://bytes.com/topic/c /answers/832994-shared_ptr-driven-classes-ambiguity-overloaded-functions
在boost的shared_ptr.h中,更改构造函数签名至:
http://bytes.com/topic/c/answers/832994-shared_ptr-derived-classes-ambiguitity-overloaded-functions
An in boost's shared_ptr.h, change the constructor signature to: