【发布时间】:2014-12-27 16:29:08
【问题描述】:
尝试使用 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() 以某种方式继承了Hndl::~Hndl() 的noexcept(false),但我不知道为什么。
有趣的是,如果我在 lambda 中注释掉对 h.impl->i 的赋值,同样的代码也会编译。
如果我从Hndl::~Hndl() 中删除noexcept(false) 规范,也会编译,但我需要它(解释原因可能有点长,但我愿意)。
如果 lambda 通过 ref 捕获,也会编译,但这里的重点是能够复制共享实现的句柄。
将noexcept(true) 添加到Impl::~Impl() 没有帮助。
ideone.com 的 c++11 编译器很高兴地按原样编译它。
谁能解释一下这里发生了什么?
【问题讨论】:
标签: c++ c++11 lambda libc++ noexcept