Hi all,
Can anyone explain why the following doesn’t compile?
#include
struct X{
typedef std::function<void(X&)> callback_type;
virtual ~X() {}
private:
callback_type _cb;
};
int main(){}
If you comment out the virtual destructor, the code compiles fine. Full error report:
################################################
CompileC build/test_function_callback.build/Debug/test_function_callback.build/Objects-normal/x86_64/main.o test_function_callback/main.cpp normal x86_64 c++ com.apple.compilers.llvm.clang.1_0.compiler
cd /Volumes/ssd/code/sandbox/test_function_callback
setenv LANG en_US.US-ASCII
/Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x c++ -arch x86_64 -fmessage-length=0 -std=gnu++11 -stdlib=libc++ -Wno-trigraphs -fpascal-strings -O0 -Wno-missing-field-initializers -Wno-missing-prototypes -Wreturn-type -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wformat -Wno-missing-braces -Wparentheses -Wswitch -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wuninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wno-sign-compare -Wshorten-64-to-32 -Wno-newline-eof -Wc++11-extensions -DDEBUG=1 -isysroot /Applications/Xcode45-DP2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk -fasm-blocks -Wdeprecated-declarations -Winvalid-offsetof -mmacosx-version-min=10.7 -g -fvisibility-inlines-hidden -Wno-sign-conversion -iquote /Volumes/ssd/code/sandbox/test_function_callback/build/test_function_callback.build/Debug/test_function_callback.build/test_function_callback-generated-files.hmap -I/Volumes/ssd/code/sandbox/test_function_callback/build/test_function_callback.build/Debug/test_function_callback.build/test_function_callback-own-target-headers.hmap -I/Volumes/ssd/code/sandbox/test_function_callback/build/test_function_callback.build/Debug/test_function_callback.build/test_function_callback-all-target-headers.hmap -iquote /Volumes/ssd/code/sandbox/test_function_callback/build/test_function_callback.build/Debug/test_function_callback.build/test_function_callback-project-headers.hmap -I/Volumes/ssd/code/sandbox/test_function_callback/build/Debug/include -I/Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Volumes/ssd/code/sandbox/test_function_callback/build/test_function_callback.build/Debug/test_function_callback.build/DerivedSources/x86_64 -I/Volumes/ssd/code/sandbox/test_function_callback/build/test_function_callback.build/Debug/test_function_callback.build/DerivedSources -F/Volumes/ssd/code/sandbox/test_function_callback/build/Debug -MMD -MT dependencies -MF /Volumes/ssd/code/sandbox/test_function_callback/build/test_function_callback.build/Debug/test_function_callback.build/Objects-normal/x86_64/main.d --serialize-diagnostics /Volumes/ssd/code/sandbox/test_function_callback/build/test_function_callback.build/Debug/test_function_callback.build/Objects-normal/x86_64/main.dia -c /Volumes/ssd/code/sandbox/test_function_callback/test_function_callback/main.cpp -o /Volumes/ssd/code/sandbox/test_function_callback/build/test_function_callback.build/Debug/test_function_callback.build/Objects-normal/x86_64/main.o
In file included from /Volumes/ssd/code/sandbox/test_function_callback/test_function_callback/main.cpp:1:
In file included from /Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/…/lib/c++/v1/functional:462:
/Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/…/lib/c++/v1/type_traits:2825:19: error: invalid application of ‘sizeof’ to an incomplete type ‘X’
static_assert(sizeof(_Tp) > 0, “Type must be complete.”);
^~~~~~~~~~~
/Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/…/lib/c++/v1/type_traits:2830:15: note: in instantiation of template class ‘std::__1::__check_complete’ requested here
: private __check_complete<_Tp>
^
/Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/…/lib/c++/v1/type_traits:2812:15: note: in instantiation of template class ‘std::__1::__check_complete<X &>’ requested here
private __check_complete<_T0, _Tp…>
^
/Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/…/lib/c++/v1/type_traits:2978:15: note: in instantiation of template class ‘std::__1::__check_complete<std::__1::function<void (X &)> &, X &>’ requested here
: private __check_complete<_Fp, _Args…>
^
/Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/…/lib/c++/v1/type_traits:2989:11: note: in instantiation of template class ‘std::__1::__invokable_imp<std::__1::function<void (X &)> &, X &>’ requested here
__invokable_imp<_Fp, _Args…>::value>
^
/Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/…/lib/c++/v1/functional:1115:33: note: in instantiation of template class ‘std::__1::__invokable<std::__1::function<void (X &)> &, X &>’ requested here
template <class _Fp, bool = __invokable<_Fp&, _ArgTypes…>::value>
^
/Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/…/lib/c++/v1/functional:1163:9: note: in instantiation of default argument for ‘__callable<std::__1::function<void (X &)> >’ required here
__callable<typename decay<_Fp>::type>::value,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/…/lib/c++/v1/functional:1166:7: note: while substituting deduced template arguments into function template ‘operator=’ [with _Fp = const std::__1::function<void (X &)> &]
operator=(_Fp&&);
^
/Volumes/ssd/code/sandbox/test_function_callback/test_function_callback/main.cpp:3:8: note: definition of ‘X’ is not complete until the closing ‘}’
struct X{
^
1 error generated.
################################################
Please let me know if I should report this as a bug.
The C++ standard doesn’t say that we should use overload resolution here, and that we should instead just look for any operator= in the member’s class type M with a parameter type of exactly const M&, const volatile M&, or M. So that seems like a Clang bug (please do file a bug for this).
As it happens, we’d currently have to perform overload resolution to look up the member’s operator= anyway, since it’s needed to determine X’s operator='s exception specification, but the standard is being changed so that the exception specification is computed on demand (this is core issue 1330, and we do not yet implement this part of it).