Hello. I'm trying to compile this code, but it doesn't do the trick and
I don't know why.
struct print
{
typedef void result_type;
template <class T>
void operator()(const T & elem) const
{
std::cout << elem << std::endl;
}
};
template
::type * = 0) { f_(get<i>(t_)); typename boost::mpl::if_c, tuple_for_each_helper
>::type(t_, f_)(); } };
template
Germán Diago Gómez wrote:
Hello. I'm trying to compile this code, but it doesn't do the trick and I don't know why.
Without looking into further details, the following is a misuse of enable_if:
template
struct tuple_for_each_helper { private: Tuple & t_; UnaryF f_; public: typedef typename UnaryF::result_type result_type; tuple_for_each_helper(Tuple & t, UnaryF f) : t_(t), f_(f) { }
result_type operator()(typename boost::enable_if
, void> ::type * = 0)
Here is the error: Your are trying to use enable_if/SFINAE in an "unprotected" context. What does that mean? SFINAE causes a *silent* failure during an *attempt* to instantiate a template. The only template here is tuple_for_each_helper which was already instantiated, before the actual failure could take place. a) If you want to SFINAE-shield operator(), you have to define that operator as a function template. b) If you want to prevent to SFINAE-shield the complete tuple_for_each_helper class template, you have to add one further "SFINAE" template parameter to the class template and you have to add the SFINAE expression there. It's rather easy, if you medidate about this for a while: Once an class template *is* instantiated, all member *declarations* (this is the short rule) must be valid. This is obviously not the case for the member operator(), *if* enable_if does not have a member type. Greetings from Bremen, Daniel Krügler
Daniel Krügler wrote:
Germán Diago Gómez wrote:
SFINAE causes a *silent* failure during an *attempt* to instantiate a template. The only template here is tuple_for_each_helper which was already instantiated, before the actual failure could take place.
Usage of bad language on my side: SFINAE's power occurs during the attempt of template argument substituition. Failing substitution leads to failing argument deduction and this again prevents template successful instantiation. Greetings from Bremen, Daniel Krügler
2008/5/6 Daniel Krügler
Daniel Krügler wrote:
Germán Diago Gómez wrote:
SFINAE causes a *silent* failure during an *attempt* to instantiate a template. The only template here is tuple_for_each_helper which was already instantiated, before the actual failure could take place.
Usage of bad language on my side: SFINAE's power occurs during the attempt of template argument substituition. Failing substitution leads to failing argument deduction and this again prevents template successful instantiation.
Greetings from Bremen,
Daniel Krügler
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Thanks all for the great response!! I'll try David Abraham's solution.
Hi!
I had a similar question already. Please take a look at my post and answer
from Dave Abrahams
http://archive.netbsd.se/?ml=boost-users&a=2007-10&t=5555956
With Kind Regards,
Ovanes
On Tue, May 6, 2008 at 1:23 PM, Germán Diago Gómez
Hello. I'm trying to compile this code, but it doesn't do the trick and I don't know why.
struct print { typedef void result_type;
template <class T> void operator()(const T & elem) const { std::cout << elem << std::endl; } };
template
struct tuple_for_each_helper { private: Tuple & t_; UnaryF f_; public: typedef typename UnaryF::result_type result_type; tuple_for_each_helper(Tuple & t, UnaryF f) : t_(t), f_(f) { }
result_type operator()(typename boost::enable_if
, void> ::type * = 0) { f_(get<i>(t_)); typename boost::mpl::if_c, tuple_for_each_helper
::type(t_, f_)(); } }; template
struct tuple_for_each_helper { typedef typename UnaryF::result_type result_type; tuple_for_each_helper(Tuple & t, UnaryF f) {} result_type operator()() {} };
template
typename result_of ::type tuple_for_each (Tuple & t, UnaryF f, typename boost::enable_if , void> >::type * = 0) { tuple_for_each_helper (t, f)(); } int main(int argc, char * argv[]) { tuple
t(3, 5.3, "hello", "goodbye"); tuple_for_each(t, print()); } And the error is:
tuple_each.cpp: In function 'int main(int, char**)': tuple_each.cpp:99: error: no matching function for call to 'tuple_for_each(std::tr1::tuple
, std::basic_string , std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass>&, print)' If I change boost::enable_if by boost::disable_if the code compiles. But if I check typeid(typename print::result_type).name() and typeid(result_of
::type).name() they are the same. I'm using g++ 4.2.3 and boost 1.34.1. Thanks in advance.
Sorry the location below deleted '<' '>' characters which are essential for
templates. Take a look at this location:
http://lists.boost.org/boost-users/2007/11/31849.php
On Tue, May 6, 2008 at 2:26 PM, Ovanes Markarian
Hi!
I had a similar question already. Please take a look at my post and answer from Dave Abrahams
http://archive.netbsd.se/?ml=boost-users&a=2007-10&t=5555956
With Kind Regards, Ovanes
On Tue, May 6, 2008 at 1:23 PM, Germán Diago Gómez
wrote: Hello. I'm trying to compile this code, but it doesn't do the trick and I don't know why.
struct print { typedef void result_type;
template <class T> void operator()(const T & elem) const { std::cout << elem << std::endl; } };
template
struct tuple_for_each_helper { private: Tuple & t_; UnaryF f_; public: typedef typename UnaryF::result_type result_type; tuple_for_each_helper(Tuple & t, UnaryF f) : t_(t), f_(f) { }
result_type operator()(typename boost::enable_if
, void> ::type * = 0) { f_(get<i>(t_)); typename boost::mpl::if_c, tuple_for_each_helper
::type(t_, f_)(); } }; template
struct tuple_for_each_helper { typedef typename UnaryF::result_type result_type; tuple_for_each_helper(Tuple & t, UnaryF f) {} result_type operator()() {} };
template
typename result_of ::type tuple_for_each (Tuple & t, UnaryF f, typename boost::enable_if , void> >::type * = 0) { tuple_for_each_helper (t, f)(); } int main(int argc, char * argv[]) { tuple
t(3, 5.3, "hello", "goodbye"); tuple_for_each(t, print()); } And the error is:
tuple_each.cpp: In function 'int main(int, char**)': tuple_each.cpp:99: error: no matching function for call to 'tuple_for_each(std::tr1::tuple
, std::basic_string , std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass, std::tr1::_NullClass>&, print)' If I change boost::enable_if by boost::disable_if the code compiles. But if I check typeid(typename print::result_type).name() and typeid(result_of
::type).name() they are the same. I'm using g++ 4.2.3 and boost 1.34.1. Thanks in advance.
Hi all, How can I get the first "bounded type" of a variant? I see there's a public typedef there: typedef typename mpl::transform< recursive_enabled_types , unwrap_recursivempl::_1 >::type types; but I don't realize how I can "extract" the type from here. I need something like this: MyVariantType v; MyVariantType::FirstBoundedType *value = getMyVariantType::FirstBoundedType(&v); Thank you! _________________________________________________________________ Invite your mail contacts to join your friends list with Windows Live Spaces. It's easy! http://spaces.live.com/spacesapi.aspx?wx_action=create&wx_url=/friends.aspx&mkt=en-us
You can apply the visitor to the variant and receive the instance of the
stored type.
With Kind Regards,
Ovanes
On Tue, May 6, 2008 at 3:05 PM, Igor R.
Hi all,
How can I get the first "bounded type" of a variant? I see there's a public typedef there:
typedef typename mpl::transform< recursive_enabled_types , unwrap_recursivempl::_1 >::type types;
but I don't realize how I can "extract" the type from here. I need something like this:
MyVariantType v; MyVariantType::FirstBoundedType *value = getMyVariantType::FirstBoundedType(&v);
Thank you!
------------------------------ Invite your mail contacts to join your friends list with Windows Live Spaces. It's easy! Try it!http://spaces.live.com/spacesapi.aspx?wx_action=create&wx_url=/friends.aspx&mkt=en-us
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi Ovanes, Yes, I know, but that's not what need. Date: Tue, 6 May 2008 17:25:08 +0200From: om_boost@keywallet.comTo: boost-users@lists.boost.orgSubject: Re: [Boost-users] [variant] how to get 1st bounded typeYou can apply the visitor to the variant and receive the instance of the stored type.With Kind Regards,Ovanes _________________________________________________________________ Invite your mail contacts to join your friends list with Windows Live Spaces. It's easy! http://spaces.live.com/spacesapi.aspx?wx_action=create&wx_url=/friends.aspx&mkt=en-us
AMDG Igor R. wrote:
Hi Ovanes,
Yes, I know, but that's not what need.
#include
Great! Thank you!> Date: Tue, 6 May 2008 09:38:17 -0600> To: boost-users@lists.boost.org> From: watanabesj@gmail.com> Subject: Re: [Boost-users] [variant] how to get 1st bounded type> > AMDG> > Igor R. wrote:> > Hi Ovanes,> > > > Yes, I know, but that's not what need.> > > > > > #include
First I was going to suggest you to use mpl::front to retrieve the first
element of the type sequence, but the new variant doc does not state that
the first element of the type sequence will be created in the variant's
memory. I remember to read that it was once the case.
You can try this: (But I am not sure if it works or is portable)
typedef typename mpl::transform<
recursive_enabled_types
, unwrap_recursivempl::_1
>::type types;
typedef boost::mpl::front<types>::type first_type;
MyVariantType v;
first_type *value = get
Hi Ovanes,
Yes, I know, but that's not what need.
------------------------------ Date: Tue, 6 May 2008 17:25:08 +0200 From: om_boost@keywallet.com To: boost-users@lists.boost.org Subject: Re: [Boost-users] [variant] how to get 1st bounded type
You can apply the visitor to the variant and receive the instance of the stored type.
With Kind Regards, Ovanes
First I was going to suggest you to use mpl::front to retrieve the first element of the type sequence, but the new variant doc does not state that the first element of the type sequence will be created in the variant's memory. I remember to read that it was once the case.
At least, the document that appears at the site states so: http://www.boost.org/doc/libs/1_35_0/doc/html/variant/tutorial.html#variant.... http://www.boost.org/doc/libs/1_35_0/doc/html/variant/design.html#variant.de...
You can try this: (But I am not sure if it works or is portable) Yes, it seems to be what I need.
Thank you. _________________________________________________________________ Connect to the next generation of MSN Messenger http://imagine-msn.com/messenger/launch80/default.aspx?locale=en-us&source=wlmailtagline
2008/5/6 Igor R.
First I was going to suggest you to use mpl::front to retrieve the first element of the type sequence, but the new variant doc does not state that the first element of the type sequence will be created in the variant's memory. I remember to read that it was once the case.
At least, the document that appears at the site states so: [...]
http://www.boost.org/doc/libs/1_35_0/doc/html/variant/design.html#variant.de...
At least what I read here is following:
The Guarantee
All instances v of type
varianthttp://www.boost.org/doc/libs/1_35_0/doc/html/boost/variant.html
At least what I read here is following: All instances v of type variant
guarantee that v has constructed content of !!!one!!! of the types !!!Ti!!!, even if an operation on v has previously failed. For me it means that it can be T2 or TN as well.
Right, but the 1st link says: "boost::variant< int, std::string > v; By default, a variant default-constructs its first bounded type, so v initially contains int(0). If this is not desired, or if the first bounded type is not default-constructible, a variant can be constructed directly from any value convertible to one of its bounded types. " _________________________________________________________________ Invite your mail contacts to join your friends list with Windows Live Spaces. It's easy! http://spaces.live.com/spacesapi.aspx?wx_action=create&wx_url=/friends.aspx&mkt=en-us
On Tue, May 6, 2008 at 6:31 PM, Igor R.
At least what I read here is following: All instances v of type varianthttp://www.boost.org/doc/libs/1_35_0/doc/html/boost/variant.html
guarantee that v has constructed content of !!!one!!! of the types !!!T*i!!!*, even if an operation on v has previously failed. For me it means that it can be T2 or TN as well. Right, but the 1st link says: "*boost::variant*http://www.boost.org/doc/libs/1_35_0/doc/html/boost/variant.html< int, std::string > v; By default, a variant default-constructs its first bounded type, so vinitially contains int(0). If this is not desired, or if the first bounded type is not default-constructible, a variant can be constructed directly from any value convertible to one of its bounded types. "
Igor, I assume the following:
If the first type throws an exception while creation the second is created and so forth and the exception is probably not reported to you. Your pointer can be NULL in your previous example. Why don't you like visitor to dispatch the type stored in the variant? Regards, Ovanes
AMDG Ovanes Markarian wrote:
Igor, I assume the following: If the first type throws an exception while creation the second is created and so forth and the exception is probably not reported to you.
Last time I checked, the variant's default constructor will construct the first type and if it fails will simply propagate the exception. If an operation succeeds, than it is safe to assume that the variant holds what you tried to put in. In Christ, Steven Watanabe
Hi Ovanes,
Igor, I assume the following:> If the first type throws an exception while creation the second is created and so forth and the exception is probably not reported to you.
No, as Steven aready wrote, that's not what happens.
Why don't you like visitor to dispatch the type stored in the variant?
I like it very much, and I use variant because of the power of the static visiting mechanism. The reason I wanted to test if the variant contains its 1st type is the following: my variant is made of a list of shared-pointers to various types; there's a routine that initializes it with one of the types depending on some conditions, then it applies some visitor on the resulting variant and stores it then in a container - however, there's no "default" behavior, so if neither condition was met, the variant remains "uninitialized" - i.e. it contains 1st type "zero" ptr. I want neither apply the visitor on "empty" smartpointer nor store it in the container, so I have to know whether it was "really" created or not. Two simple ways I can think about are to test the resulting variant or to introduce some flag - of course, both ways are far from ideal... _________________________________________________________________ Connect to the next generation of MSN Messenger http://imagine-msn.com/messenger/launch80/default.aspx?locale=en-us&source=wlmailtagline
Why don't you like visitor to dispatch the type stored in the variant?
I like it very much, and I use variant because of the power of the
static visiting mechanism.
The reason I wanted to test if the variant contains its 1st type is the
following: my variant is made of a list of shared-pointers to various
types; there's a routine that initializes it with one of the types
depending on some conditions, then it applies some visitor on the
resulting variant and stores it then in a container - however, there's
no "default" behavior, so if neither condition was met, the variant
remains "uninitialized" - i.e. it contains 1st type "zero" ptr. I want
neither apply the visitor on "empty" smartpointer nor store it in the
container, so I have to know whether it was "really" created or not. Two
simple ways I can think about are to test the resulting variant or to
introduce some flag - of course, both ways are far from ideal...
struct my_visitor {
typedef bool return_type;
vector
Oop! sorry, I did not intend to send that yet -- I was toying with the
problem discussed in this thread but my finger slipped.. :(
________________________________
From: John Femiani
Sent: Wednesday, May 07, 2008 2:53 AM
To: 'boost-users@lists.boost.org'
Subject: RE: [Boost-users] [variant] how to get 1st bounded type
> Why don't you like visitor to dispatch the type stored in the
variant?
I like it very much, and I use variant because of the power of
the static visiting mechanism.
The reason I wanted to test if the variant contains its 1st type
is the following: my variant is made of a list of shared-pointers to
various types; there's a routine that initializes it with one of the
types depending on some conditions, then it applies some visitor on the
resulting variant and stores it then in a container - however, there's
no "default" behavior, so if neither condition was met, the variant
remains "uninitialized" - i.e. it contains 1st type "zero" ptr. I want
neither apply the visitor on "empty" smartpointer nor store it in the
container, so I have to know whether it was "really" created or not. Two
simple ways I can think about are to test the resulting variant or to
introduce some flag - of course, both ways are far from ideal...
struct my_visitor {
typedef bool return_type;
vector
Igor R. wrote:
The reason I wanted to test if the variant contains its 1st type is the following: my variant is made of a list of shared-pointers to various types; there's a routine that initializes it with one of the types depending on some conditions, then it applies some visitor on the resulting variant and stores it then in a container - however, there's no "default" behavior, so if neither condition was met, the variant remains "uninitialized" - i.e. it contains 1st type "zero" ptr. I want neither apply the visitor on "empty" smartpointer nor store it in the container, so I have to know whether it was "really" created or not.
Um, wrap the variant in boost::optional?
Hmm... how could I miss such a straightforward solution?? :) Thank you!> Date: Wed, 7 May 2008 22:18:11 -0400> From: nat@lindenlab.com> To: boost-users@lists.boost.org> Subject: Re: [Boost-users] [variant] how to get 1st bounded type> > Igor R. wrote:> > > The reason I wanted to test if the variant contains its 1st> > type is the following: my variant is made of a list> > of shared-pointers to various types; there's a routine that> > initializes it with one of the types depending on some> > conditions, then it applies some visitor on the resulting> > variant and stores it then in a container - however, there's> > no "default" behavior, so if neither condition was met, the> > variant remains "uninitialized" - i.e. it contains 1st type> > "zero" ptr. I want neither apply the visitor on "empty"> > smartpointer nor store it in the container, so I have to> > know whether it was "really" created or not. > > Um, wrap the variant in boost::optional?> _______________________________________________> Boost-users mailing list> Boost-users@lists.boost.org> http://lists.boost.org/mailman/listinfo.cgi/boost-users _________________________________________________________________ Discover the new Windows Vista http://search.msn.com/results.aspx?q=windows+vista&mkt=en-US&form=QBRE
Max wrote:
Hmm... how could I miss such a straightforward solution?? :)
how is this solution straightforward? Please elaborate.
The OP stated that sometimes he needs his type to express "none of the above." boost::optional is specifically intended to distinguish the case in which you have no meaningful value -- rather like SQL's NULL.
Exactly. Anyway, it was very useful to find-out how to access the variant bounded types, since it would be applicable in some other scenarios...> Max wrote:> > >> Hmm... how could I miss such a straightforward solution?? :)> > > > how is this solution straightforward? Please elaborate.> > The OP stated that sometimes he needs his type to express "none of the > above." boost::optional is specifically intended to distinguish the case > in which you have no meaningful value -- rather like SQL's NULL. _________________________________________________________________ Invite your mail contacts to join your friends list with Windows Live Spaces. It's easy! http://spaces.live.com/spacesapi.aspx?wx_action=create&wx_url=/friends.aspx&mkt=en-us
AMDG Ovanes Markarian wrote:
At least what I read here is following:
The Guarantee
All instances |v| of type |variant http://www.boost.org/doc/libs/1_35_0/doc/html/boost/variant.html
| guarantee that |v| has constructed content of !!!one!!! of the types |!!!T/i!!!/|, even if an operation on |v| has previously failed. For me it means that it can be T2 or TN as well.
If, variant could only hold the first type there would be no reason to use it. The whole point of variant is that it can hold any of the types in the list. In Christ, Steven Watanabe
participants (9)
-
Daniel Krügler
-
Germán Diago
-
Germán Diago Gómez
-
Igor R.
-
John Femiani
-
Max
-
Nat Goodspeed
-
Ovanes Markarian
-
Steven Watanabe