C++0x中的std::shared_ptr和boost::shared_ptr有何区别?

9

我有一份使用了 shared_ptr 和 STL 的 C++ 代码。一个常见的头文件如下:

#include<boost/shared_ptr.hpp>
using boost::shared_ptr;  // for shared_ptr
using namespace std;      // for STL

我想现在转换到c++0x,以利用语言特性,使用gcc 4.6和-std=c++0x。然而现在有了std::shared_ptr,会对未指定的shared_ptrboost::shared_ptr vs std::shared_ptr)造成歧义。

当转换为std::shared_ptr时,像这样:

#include<memory>
using namespace std;      // for STL; also imports std::shared_ptr

然后我遇到了与 boost::python 相关的问题,显然它只能与 boost::shared_ptr 一起使用(至少没有进一步的调整):

/usr/include/boost/python/object/make_ptr_instance.hpp:30:52: error: no matching function for call to 'get_pointer(const std::shared_ptr<Cell>&)'

我的问题是:

  • 除了暂时不使用C++0x,是否有简单的解决方案来解决boost::shared_ptrstd::shared_ptr之间的歧义?
  • boost::shared_ptr最终是否会成为std::shared_ptr的别名?这将自动解决我的问题。

谢谢!


7
最好的解决方法可能是完全摒弃using namespace std。这可能只需要对所有STL元素进行全局查找和替换即可,非常简单。 - stijn
对,那确实是解决方案,但 STL 使用非常频繁,这会使代码变得不太易读。也许我可以考虑在公共头文件中编写一堆 using std::string; using std::vector; 等声明。实际上并没有使用很多 std:: 部分,但它们被经常使用。 - eudoxos
2
@eudoxos:需要一些时间来适应,但代码的易读性会大大提高;此外,我发现自己只需在使用它的范围内添加 using std::cout; using std::string。这增加了可读性,特别是在不太琐碎的情况下(例如 using boost::phoenix::bindusing boost:bind,或 using boost::spirit::karma::_1 等)。这样可以消除任何歧义(对编译器和程序员都是如此),而不会使实际代码混乱不堪。 - sehe
1个回答

3
您需要为共享指针类定义自由函数“get_pointer”,才能使其与Boost Python一起使用。(请注意,这使您能够编写自己的共享指针,并仍然与Boost Python一起使用:这是有意设计的努力,以防止不同的Boost库之间紧密耦合)。您可以尝试使用boost tr1兼容头文件来实现,但我没有尝试过。

http://boost.cowic.de/rc/pdf/tr1.pdf


当Boost.TR1配置为使用您的标准库本地TR1实现时,它并没有做太多事情:它只是包含了适当的头文件。
当Boost.TR1使用特定组件的Boost实现时,它会包含适当的Boost头文件,并使用using声明在命名空间std::tr1中导入必要的声明。请注意,只有那些属于标准的声明才会被导入:实现故意非常严格,不包括任何Boost特定的扩展,以便捕获用户代码中的任何可移植性错误。如果您确实需要使用特定于Boost的扩展,则应直接包含Boost头文件并在命名空间boost::中使用声明。请注意,这种实现风格并不完全符合标准,特别是无法将用户定义的TR1组件模板专业化添加到命名空间std::tr1中。还有一两个Boost库尚未完全符合标准,任何此类不符合都在TR1按主题部分中有所记录。然而,希望在实践中发生非标准行为的情况应该极为罕见。
如果您使用符合标准的头文件包含(在boost/tr1/tr1中),则这些头文件名称有时可能与现有的标准库头文件发生冲突(例如shared_ptr会添加到现有的标准库头文件而不是它自己的头文件中)。这些头文件以两种方式之一转发到现有的标准库头文件:对于gcc,它使用#include_next,对于其他编译器,它使用宏BOOST_TR1_STD_HEADER(在boost/tr1/detail/config.hpp中定义),该宏计算为#include <../include/header>。这应该对大多数编译器“开箱即用”,但这意味着这些头文件永远不应放置在已经在您的编译器搜索路径中的名为“include”的目录中。

谢谢!我本以为使用boost::python会更复杂。现在我也使用了boost::serialization,但它似乎并不那么灵活(例如,这个线程建议一份拷贝并自定义boost::serialization对于boost::shared_ptr所做的事情)。 - eudoxos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接