隐式实例化未定义模板:Boost Bug或Clang Bug?

时间:2012-03-06 00:13:39

标签: c++ boost clang shared-ptr

我试图编译一些使用Boost(1.49)的代码,使用来自trunk的Cla​​ng(& libc ++)。 有问题的代码可归结为以下内容:

#include <memory>
#include <boost/signals2.hpp>

int main()
{
    std::shared_ptr<int> s;
}

使用Clang编译时,会发出以下消息:

$ clang++ -I/home/alexander/usr/local/include --stdlib=libc++ -std=c++0x signals2-bug.cpp   -o signals2-bug
signals2-bug.cpp:6:26: error: implicit instantiation of undefined template
      'std::shared_ptr<int>'
    std::shared_ptr<int> s;
                         ^
/home/alexander/usr/local/include/boost/signals2/detail/foreign_ptr.hpp:24:30: note: 
      template is declared here
  template<typename T> class shared_ptr;
                         ^

boost / signals2 / detail / foreign_ptr.hpp中的违规行是:

#if !defined(BOOST_INTEL_STDCXX0X)
namespace std
{
  template<typename T> class shared_ptr;
  template<typename T> class weak_ptr;
}
#endif

现在应该责怪谁?

我想到了两件事:

  1. 为什么Boost.Signals标头感觉需要声明自己的shared_ptr?有什么好处?
  2. Boost.Signals中的行看起来像一个简单的前向声明。如果它出现在模板定义之后,为什么会出现问题呢?
  3. 修改

    这似乎是一个Boost.Signals2错误,因为根据ISO / IEC C ++ 2011标准第17.6.4.2.1节,std :: namespace中的事物声明会导致未定义的行为:

      

    如果添加声明或者C ++程序的行为是未定义的   命名空间std或命名空间std中的命名空间的定义   除非另有规定。程序可以添加模板   专业化       对于任何标准库模板到命名空间std,仅当声明取决于用户定义的类型时        并且专业化符合原始模板的标准库要求,并未明确说明       禁止的。

    已创建Boost错误跟踪器中的故障单:https://svn.boost.org/trac/boost/ticket/6655

    请注意,此处还存在一个Clang错误:http://llvm.org/bugs/show_bug.cgi?id=10521,但实施者指出违规行为。

    Google员工的后续行动

    问题确实是一个Boost错误。这个changeset 77289应该解决Boost 1.50的问题。 Clang中相应的Bug被标记为无效。

1 个答案:

答案 0 :(得分:-1)

foreign_ptr.hpp中的代码是重新声明(如果已经定义shared_ptr),因此不太可能导致问题(向std添加声明是技术上未定义的行为,但是大多数编译器都不关心,因为它们并没有真正区分标准库头和其他文件)。因此,错误只能由shared_ptr实际上未定义引起。

现在libc++显然有一个定义shared_ptr,所以我只能怀疑某些C ++ 03库以某种方式进入了包含路径并且优先于libc ++。