我试图编译一些使用 Boost (1.49) 的代码,并使用 trunk 中的 Clang(& 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
现在该怪谁呢?
我想到两件事:
- 为什么 Boost.Signals 标头需要声明自己的共享指针?有什么收获?
- Boost.Signals 中的行看起来像一个简单的前向声明。如果它出现在模板定义之后,为什么会出现问题?
EDIT
这似乎是一个 Boost.Signals2 错误,因为根据 ISO/IEC C++ 2011 标准第 17.6.4.2.1 节,std:: 命名空间中的事物声明会导致未定义的行为:
如果 C++ 程序添加声明或
命名空间 std 或命名空间 std 内的命名空间的定义
除非另有规定。程序可以添加模板
专业化
对于任何标准库模板,仅当声明依赖于用户定义类型时才到名称空间 std
并且专业化满足原始模板的标准库要求,并且没有明确
禁止。
Boost bug 跟踪器中的票证已创建:https://svn.boost.org/trac/boost/ticket/6655
请注意,这里也存在一个 Clang bug:http://llvm.org/bugs/show_bug.cgi?id=10521,但是实施者指出存在违规行为。
Google 员工的后续行动:
问题确实是 Boost 的 bug。这变更集 77289应该可以解决 Boost 1.50 的问题。
Clang 中相应的 Bug 被标记为无效。