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.
どういうわけかofImpl::L::~L()
を継承しているように見えますが、その理由はわかりません。興味深いことに、ラムダ内への割り当てをコメントアウトすると、同じコードがコンパイルされます。から仕様を削除してもコンパイルされますが、それが必要です (理由を説明するには少し長くなりますが、そうします)。ラムダが参照によってキャプチャされた場合もコンパイルしますが、ここでのポイントは、実装を共有するハンドルをコピーできることです。に追加しても役に立ちません。noexcept(false)
Hndl::~Hndl()
h.impl->i
noexcept(false)
Hndl::~Hndl()
noexcept(true)
Impl::~Impl()
ideone.com の c++11 コンパイラは、喜んでそのままコンパイルします。
ここで何が起こっているのか誰か説明してくれませんか?