Versuchen, den folgenden Code mit der Clang-Version in Xcode 6.1 (clang-600.0.54 basierend auf LLVM 3.5svn) zu kompilieren, mit -std=c++11
und -stdlib=libc++
gibt mir einige Fehler, die ich nicht wirklich verstehe.Warum bekomme ich "Exception spec is lax als base" Fehler mit diesem Stück Code?
#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;
}
Ergebnisse:
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.
Sieht aus, als ob Impl::L::~L()
irgendwie die noexcept(false)
von Hndl::~Hndl()
erbt, aber ich weiß nicht, warum. Interessanterweise kompiliert der gleiche Code, wenn ich die Zuordnung zu h.impl->i
innerhalb des Lambda auskommentieren. Kompiliert auch, wenn ich die noexcept(false)
Spezifikation von Hndl::~Hndl()
entferne, aber ich brauche das (wäre ein bisschen lang zu erklären, warum, aber ich tue). Kompiliert auch, wenn das Lambda durch ref erfasst, aber der ganze Punkt hier wäre in der Lage sein, Griffe zu kopieren, die eine Implementierung teilen. Das Hinzufügen von noexcept(true)
zu Impl::~Impl()
hilft nicht.
Der C++ 11-Compiler von ideone.com kompiliert sie gerne so, wie sie ist.
Kann mir jemand erklären, was hier passiert?
Ist das explizit im Standard erlaubt? [This] (http://en.cppreference.com/w/cpp/utility/functional/function/~function) Referenz besagt, dass "~ Funktion" hat "noexpect" Spezifizierer, aber es kann falsch sein (wieder). – dewaffled
'std :: function' hat definitiv einen 'noexcept'-Destruktor, aber es sollte immer noch möglich sein, Typen zu speichern, die das nicht tun. Wenn dein Destruktor nicht wirklich wirft, gibt es kein Problem und das Programm sollte einwandfrei funktionieren. Wenn Ihr Destruktor bei der Speicherung in einer 'std :: function 'auslöst, würde dies zu einem Aufruf von' std :: terminate() ' –
@imre führen. Daher funktioniert der Code nicht, wenn der Destruktor trotzdem einen Wurf ausführt. Ich sehe keinen Grund, es als "noexcept (false)" zu deklarieren. – dewaffled