尝试使用 Xcode 6.1 中的 clang 版本(基于 LLVM 3.5svn 的 clang-600.0.54)编译以下代码,-std=c++11
并-stdlib=libc++
给出了一些我不太理解的错误。
#include <functional>
struct Impl
{
typedef std::function<void ()> L;
L l;
int i;
};
struct Hndl
{
Impl* impl;
Hndl(Impl* i): impl(i) {}
~Hndl() noexcept(false) {}
};
int main(int argc, char * argv[]) {
Hndl h(new Impl());
h.impl->l = [=]
{
h.impl->i = 42;
};
return 0;
}
结果:
In file included from t.cpp:1:
/Applications/Xcode-6.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:1293:52: error: exception specification of overriding
function is more lax than base version
template<class _FD, class _Alloc, class _FB> class __func;
^
/Applications/Xcode-6.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:1593:13: note: in instantiation of template class
'std::__1::__function::__func<<lambda at t.cpp:20:14>, std::__1::allocator<<lambda at t.cpp:20:14> >, void ()>' requested here
if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value)
^
/Applications/Xcode-6.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:1697:5: note: in instantiation of function template
specialization 'std::__1::function<void ()>::function<<lambda at t.cpp:20:14> >' requested here
function(_VSTD::forward<_Fp>(__f)).swap(*this);
^
t.cpp:20:12: note: in instantiation of function template specialization 'std::__1::function<void ()>::operator=<<lambda at t.cpp:20:14> >' requested here
h.impl->l = [=]
^
/Applications/Xcode-6.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:1281:39: note: overridden virtual function is here
_LIBCPP_INLINE_VISIBILITY virtual ~__base() {}
^
1 error generated.
看起来好像Impl::L::~L()
以某种方式继承了noexcept(false)
of Hndl::~Hndl()
,但我不知道为什么。有趣的是,如果我注释掉h.impl->i
lambda 内部的赋值,同样的代码也会编译。如果我从中删除noexcept(false)
规范,也会编译Hndl::~Hndl()
,但我需要它(解释原因会有点长,但我这样做了)。如果 lambda 通过 ref 捕获,也会编译,但这里的重点是能够复制共享实现的句柄。添加noexcept(true)
到Impl::~Impl()
没有帮助。
ideone.com 的 c++11 编译器很高兴地按原样编译它。
谁能解释一下这里发生了什么?