Recursive boost::variant type doesn't compile with "-std=c++11 -stdlib=libc++"

boost, c++, c++11, clang, compiler-errors

Solution

`boost::recursive_wrapper<foo>` is the tool to deal with incomplete types, while still maintaining the illusion for e.g. visitors that a variant really hold a `foo`.

Problem

Consider the following code: ``` #include <vector> #include <boost/variant.hpp> struct foo; typedef boost::variant<foo> bar; struct foo { std::vector<bar> baz; }; int main () { foo f; return 0; } ``` Building on Mac OS X with Xcode 4.4 (I have boost 1.50.0 installed via Homebrew): - `clang++ test.cc`: no errors. - `clang++ -stdlib=libc++ test.cc`: no errors. - `clang++ -std=c++11 test.cc`: no errors. - `clang++ -std=c++11 -stdlib=libc++ test.cc`: lots of errors! ``` /usr/local/include/boost/type_traits/has_nothrow_constructor.hpp:24:40: error: incomplete type 'foo' used in type trait expression BOOST_STATIC_CONSTANT(bool, value = BOOST_HAS_NOTHROW_CONSTRUCTOR(T)); ^ ...snip... test.cc:10:19: note: in instantiation of template class '...snip...' requested here std::vector<bar> baz; ^ test.cc:8:8: note: definition of 'foo' is not complete until the closing '}' struct foo ^ /usr/local/include/boost/mpl/next_prior.hpp:31:22: error: type 'int' cannot be used prior to '::' because it has no members typedef typename T::next type; ^ test.cc:10:19: note: in instantiation of template class '...snip...' requested here std::vector<bar> baz; ^ /usr/local/include/boost/mpl/sizeof.hpp:27:20: error: invalid application of 'sizeof' to an incomplete type 'foo' : mpl::size_t< sizeof(T) > ^~~~~~~~~ test.cc:10:19: note: in instantiation of template class '...snip...' requested here std::vector<bar> baz; ^ test.cc:8:8: note: definition of 'foo' is not complete until the closing '}' struct foo ^ ...big snip... 8 errors generated. ``` What's going on here? Why can't I compile this with the options specified? Is there any way to solve this?

Original source