const_string + recursive_variant = boom

I've been trying to build a generic "message" type class using boost.variant and have just run across a problem when trying to convert it from using std::string to using the proposed boost::const_string. Attached is a small test case and the output from gcc 3.3.2 (the latter gzipped due to its hugeness). All is well if the mystring type is std::string. Any thoughts on how to fix this? -- Caleb Epstein caleb.epstein@gmail.com

I striped the sample down to: typedef make_recursive_variant<int, std::pair<int, recursive_variant_> >::type value; value v; Which compiles fine with MS VC 7.1 and fails to compile on Intel C++ 8. Here is Intel output: C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7/include/utility(51): error: incomplete type is not allowed _Ty2 second; // the second stored value ^ detected during: instantiation of class "std::pair<_Ty1, _Ty2> [with _Ty1=int, _Ty2=boost::recursive_variant_]" at line 252 of "D:\lib\boost\boost/variant/detail/visitation_impl.hpp" instantiation of "Visitor::result_type boost::detail::variant::visitation_impl(const int, const int, Visitor &, VoidPtrCV, boost::mpl::false_, NoBackupFlag, Which *, step0 *) [with Which=boost::mpl::int_<0>, step0=boost::detail::variant::visitation_impl_step<boost::mpl::begin<boo st::variant<boost::detail::variant::recursive_flag<int>, std::pair<int, boost::recursive_variant_>, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>::recursive_enabled_types>::type, boost::mpl::end<boost::variant<boost::detail::variant::recursive_flag<in t>, std::pair<int, boost::recursive_variant_>, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>::recursive_enabled_types>::type>, Visitor=boost::detail::variant::destroyer, VoidPtrCV=void *, NoBackupFlag=boost::variant<boost::detail::variant::recursive_flag<int>, std::pair<int, boost::recursive_variant_>, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>::has_fallback_type_]" at line 1738 of "D:\lib\boost\boost/variant/variant.hpp" instantiation of "Visitor::result_type boost::variant<T0_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::internal_apply_visitor_impl(int, int, Visitor &, VoidPtrCV) [with T0_=boost::detail::variant::recursive_flag<int>, T1=std::pair<int, boost::recursive_variant_>, T2=boost::detail::variant::void_, T3=boost::detail::variant::void_, T4=boost::detail::variant::void_, T5=boost::detail::variant::void_, T6=boost::detail::variant::void_, T7=boost::detail::variant::void_, T8=boost::detail::variant::void_, T9=boost::detail::variant::void_, T10=boost::detail::variant::void_, T11=boost::detail::variant::void_, T12=boost::detail::variant::void_, T13=boost::detail::variant::void_, T14=boost::detail::variant::void_, T15=boost::detail::variant::void_, T16=boost::detail::variant::void_, T17=boost::detail::variant::void_, T18=boost::detail::variant::void_, T19=boost::detail::variant::void_, Visitor=boost::detail::variant::destroyer, VoidPtrCV=void *]" at line 1749 of "D:\lib\boost\boost/variant/variant.hpp" instantiation of "Visitor::result_type boost::variant<T0_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::internal_apply_visitor(Visitor &) [with T0_=boost::detail::variant::recursive_flag<int>, T1=std::pair<int, boost::recursive_variant_>, T2=boost::detail::variant::void_, T3=boost::detail::variant::void_, T4=boost::detail::variant::void_, T5=boost::detail::variant::void_, T6=boost::detail::variant::void_, T7=boost::detail::variant::void_, T8=boost::detail::variant::void_, T9=boost::detail::variant::void_, T10=boost::detail::variant::void_, T11=boost::detail::variant::void_, T12=boost::detail::variant::void_, T13=boost::detail::variant::void_, T14=boost::detail::variant::void_, T15=boost::detail::variant::void_, T16=boost::detail::variant::void_, T17=boost::detail::variant::void_, T18=boost::detail::variant::void_, T19=boost::detail::variant::void_, Visitor=boost::detail::variant::destroyer]" at line 1157 of "D:\lib\boost\boost/variant/variant.hpp" instantiation of "void boost::variant<T0_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::destroy_content() [with T0_=boost::detail::variant::recursive_flag<int>, T1=std::pair<int, boost::recursive_variant_>, T2=boost::detail::variant::void_, T3=boost::detail::variant::void_, T4=boost::detail::variant::void_, T5=boost::detail::variant::void_, T6=boost::detail::variant::void_, T7=boost::detail::variant::void_, T8=boost::detail::variant::void_, T9=boost::detail::variant::void_, T10=boost::detail::variant::void_, T11=boost::detail::variant::void_, T12=boost::detail::variant::void_, T13=boost::detail::variant::void_, T14=boost::detail::variant::void_, T15=boost::detail::variant::void_, T16=boost::detail::variant::void_, T17=boost::detail::variant::void_, T18=boost::detail::variant::void_, T19=boost::detail::variant::void_]" at line 1164 of "D:\lib\boost\boost/variant/variant.hpp" instantiation of "boost::variant<T0_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::~variant() [with T0_=boost::detail::variant::recursive_flag<int>, T1=std::pair<int, boost::recursive_variant_>, T2=boost::detail::variant::void_, T3=boost::detail::variant::void_, T4=boost::detail::variant::void_, T5=boost::detail::variant::void_, T6=boost::detail::variant::void_, T7=boost::detail::variant::void_, T8=boost::detail::variant::void_, T9=boost::detail::variant::void_, T10=boost::detail::variant::void_, T11=boost::detail::variant::void_, T12=boost::detail::variant::void_, T13=boost::detail::variant::void_, T14=boost::detail::variant::void_, T15=boost::detail::variant::void_, T16=boost::detail::variant::void_, T17=boost::detail::variant::void_, T18=boost::detail::variant::void_, T19=boost::detail::variant::void_]"
-----Original Message----- From: Caleb Epstein [mailto:caleb.epstein@gmail.com] Sent: Thursday, November 04, 2004 9:00 PM To: boost@lists.boost.org; Maxim Yegorushkin Subject: const_string + recursive_variant = boom
I've been trying to build a generic "message" type class using boost.variant and have just run across a problem when trying to convert it from using std::string to using the proposed boost::const_string.
Attached is a small test case and the output from gcc 3.3.2 (the latter gzipped due to its hugeness). All is well if the mystring type is std::string.
Any thoughts on how to fix this?
-- Caleb Epstein caleb.epstein@gmail.com

On Thu, 4 Nov 2004 22:18:29 +0300, Maxim Yegorushkin <e-maxim@yandex.ru> wrote:
I striped the sample down to:
typedef make_recursive_variant<int, std::pair<int, recursive_variant_> >::type value; value v;
Which compiles fine with MS VC 7.1 and fails to compile on Intel C++ 8.
Well this code compiles fine on g++ 3.3.2 and g++ 3.4.2. I tried g++ 3.4.2 on my original example and it gives basically the same results as 3.3.2 (taking sizeof an incomplete type) but the compiler dies with an ICE. The newer g++ does however suggests that AllocatorT::rebind should be AllocatorT::template rebind in const_string/detail/storage.hpp, lines 79 and 86. -- Caleb Epstein caleb.epstein@gmail.com

From: Caleb Epstein [mailto:caleb.epstein@gmail.com] Subject: Re: const_string + recursive_variant = boom
On Thu, 4 Nov 2004 22:18:29 +0300, Maxim Yegorushkin <e-maxim@yandex.ru> wrote:
I striped the sample down to:
typedef make_recursive_variant<int, std::pair<int, recursive_variant_> >::type value; value v;
Which compiles fine with MS VC 7.1 and fails to compile on Intel C++
Well this code compiles fine on g++ 3.3.2 and g++ 3.4.2.
I tried g++ 3.4.2 on my original example and it gives basically the same results as 3.3.2 (taking sizeof an incomplete type) but the compiler dies with an ICE.
The newer g++ does however suggests that AllocatorT::rebind should be AllocatorT::template rebind in const_string/detail/storage.hpp, lines 79 and 86.
Well, variant's docs say little about recursive variants and standard templates (which shall not be used with incomplete types) and I am not an expert in variant architecture, so it would be nice if someone knowledgeable could clarify the issue.

Maxim, I am one of the Variant authors. Could you clarify what you mean by standard templates "shall not be used with incomplete types"---does this mean for instance that std::vector<incomplete_t> is undefined? If so, is it undefined even if such a type is even only mentioned in a program without actually ever instantiating the template? Eric Maxim Yegorushkin wrote:
From: Caleb Epstein [mailto:caleb.epstein@gmail.com] Subject: Re: const_string + recursive_variant = boom
On Thu, 4 Nov 2004 22:18:29 +0300, Maxim Yegorushkin
<e-maxim@yandex.ru> wrote:
I striped the sample down to:
typedef make_recursive_variant<int, std::pair<int, recursive_variant_> >::type value; value v;
Which compiles fine with MS VC 7.1 and fails to compile on Intel C++
8.
Well this code compiles fine on g++ 3.3.2 and g++ 3.4.2.
I tried g++ 3.4.2 on my original example and it gives basically the same results as 3.3.2 (taking sizeof an incomplete type) but the compiler dies with an ICE.
The newer g++ does however suggests that AllocatorT::rebind should be AllocatorT::template rebind in const_string/detail/storage.hpp, lines 79 and 86.
Well, variant's docs say little about recursive variants and standard templates (which shall not be used with incomplete types) and I am not an expert in variant architecture, so it would be nice if someone knowledgeable could clarify the issue.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

At 06:04 PM 11/7/2004, Eric Friedman wrote:
Maxim,
I am one of the Variant authors. Could you clarify what you mean by standard templates "shall not be used with incomplete types"---does this mean for instance that std::vector<incomplete_t> is undefined? If so, is it undefined even if such a type is even only mentioned in a program without actually ever instantiating the template?
17.4.3.6 says it is undefined "if an incomplete type (3.9) is used as a template argument when instantiating a template component." --Beman

Eric Friedman wrote:
Could you clarify what you mean by standard templates "shall not be used with incomplete types"---does this mean for instance that std::vector<incomplete_t> is undefined?
Yes, and ...
If so, is it undefined even if such a type is even only mentioned in a program without actually ever instantiating the template?
... no, but you need to be careful. Many things cause instantiation.

Peter Dimov wrote:
Eric Friedman wrote: Could you clarify what you mean by standard templates "shall not be used with incomplete types"---does this mean for instance that std::vector<incomplete_t> is undefined?
Yes, and ...
You can find rationale for that here: http://www.cuj.com/documents/s=7986/cujcexp2002austern/ -- Maxim Yegorushkin

On Mon, 08 Nov 2004 14:09:23 +0300, Maxim Yegorushkin <e-maxim@yandex.ru> wrote:
Peter Dimov wrote:
Eric Friedman wrote: Could you clarify what you mean by standard templates "shall not be used with incomplete types"---does this mean for instance that std::vector<incomplete_t> is undefined?
Yes, and ...
You can find rationale for that here: http://www.cuj.com/documents/s=7986/cujcexp2002austern/
Parts of which are wrong, unfortunately. But it is still true that the standard forbids instantiating standard library components with incomplete types. --Matt

Matt Austern wrote:
You can find rationale for that here: http://www.cuj.com/documents/s=7986/cujcexp2002austern/
Parts of which are wrong, unfortunately.
That's too bad :(. I often refer my fellow-programmers to the article... -- Maxim Yegorushkin
participants (6)
-
Beman Dawes
-
Caleb Epstein
-
Eric Friedman
-
Matt Austern
-
Maxim Yegorushkin
-
Peter Dimov