0

Possible Duplicate:
Does std::function's copy-constructor require the template type's argument types to be complete types?

I have a simple class with a callback built on std::function, but it's not building with C++11 / libc++. I think I see the error, but I don't know the solution.

#include <functional>

struct Base {
    typedef std::function<void( Base baseInstance )> Callback;

    Base() {}
    virtual ~Base() {}

    void setCallBack( Callback callback ) { mCallback = callback; }

private:
    Callback mCallback; // <--- Error, "Ivalid application of 'sizeof' to an incomplete type of 'Base'"
};

full error log:

In file included from /Volumes/ssd/code/sandbox/test_touchtracker_libcpp/test_touchtracker_libcpp/main.cpp:9:
In file included from /Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/iostream:38:
In file included from /Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/ios:216:
In file included from /Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__locale:15:
In file included from /Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/string:434:
In file included from /Applications/Xcode45-DP2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/algorithm:591:
/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 'Base'
    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:2812:15: note: in instantiation of template class 'std::__1::__check_complete<Base>' 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 (Base)> &, Base>' 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 (Base)> &, Base>' 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 (Base)> &, Base>' 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 (Base)> >' 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 (Base)> &]
      operator=(_Fp&&);
      ^
/Volumes/ssd/code/sandbox/test_touchtracker_libcpp/TouchTracker.h:5:8: note: definition of 'Base' is not complete until the closing '}'
struct Base {
       ^
1 error generated.

So, the std::function is not complete. But I want this class to be able to take a reference to a callback, to this class. So I'm in a bit of a pickle. Anyone know how to handle this with C++11?

Note: this code compiles without a problem when using <tr1/functional>

Community
  • 1
  • 1
rich.e
  • 3,660
  • 4
  • 28
  • 44
  • 2
    Also, if you want to pass a reference, *maybe* you should declare the `std::function` like that. :P `std::function` and suddenly you have no "incomplete type" errors and also no *slicing*. – Xeo Jul 14 '12 at 03:24
  • It was just a simplified example from a much larger project. And no, changing the argument to a reference does not make the error go away. – rich.e Jul 14 '12 at 17:10
  • @Xeo Can you please clarify what you meant in your comment? Because `std::function` does not work for me, so I am stuck with only being able to pass a pointer to Base. I also disagree that this is a duplicate of the linked post, since although the error is the same, my problem is with out to make a function callback that passes a reference to self as first argument. – rich.e Jul 15 '12 at 04:59
  • Well, to help with that I really need to see how you invoke the callback and pass the callback, and what the new error is, since it can't be an incomplete type error if you indeed changed to a reference. http://ideone.com/IpObb Please tell me if this code compiles under libc++. – Xeo Jul 15 '12 at 05:34
  • Thanks, no that code produces the same error as above, "invalid application of 'sizeof' to an incomplete type 'X'", stemming from `__check_complete`. If you think I have found a bug then maybe I should discuss this on the clang list? – rich.e Jul 15 '12 at 05:45
  • That might be a good idea, since I'm kinda running out of ideas here. The code definitly shouldn't produce this error. What about the following code? http://ideone.com/tHOn2 You also might wish to join the Lounge chat room, as discussing this problem would be more convenient there. – Xeo Jul 15 '12 at 05:55
  • That compiles. I think its a bug caused from the virtual destructor - commenting it out allows the code to compile. Thanks for the help though... I'm going to ask about it on the cfe-dev mailing list, since it is clearly a clang issue. – rich.e Jul 15 '12 at 06:35
  • 1
    To completely finish this off, it was discussed [here](http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-July/022986.html) and has been fixed in libc++ subversion as of a few days ago. – rich.e Jul 20 '12 at 01:56
  • Good to know, thanks for bringing that up on the mailing list. :) – Xeo Jul 20 '12 at 02:07

0 Answers0