
Hi, I have 2 fusion containers: a small vector (my_vec) and a bigger set (my_set). I want to overwrite the elements of the set with elements from the vector whenever they have the same type. Sounds simple: struct update { update(my_set_type& to_overwrite_):to_overwrite(to_overwrite_){} template<typename T> void operator()(T& elt) /*const?*/ { boost::fusion::at_key<T>(to_overwrite)=elt; } my_set_type& to_overwrite; }; boost::fusion::for_each(my_vec,update(my_set)); Except that this won't compile because the operator() is required to be const, which is sad, because it was very simple. This leaves me with the unattractive option of inverting the set and the vector inside update. Now, I iterate on the set's elements and overwrite them when found in the vector. This is unattractive because 1) the code gets really ugly 2) it could be slower (the set is bigger) and 3) it has a much bigger compile-time cost (I resorted to an enable_if of fusion::result_of::find and I make it short, it is actually much worse). I thought of using transform, but this will be slower as I will need to transform every element of the set, even for a vector of size 1. Am I missing something? If not, would it be possible to remove this constraint? Thanks, Christophe

On 10/05/2010 02:11 PM, Christophe Henry wrote:
Hi,
I have 2 fusion containers: a small vector (my_vec) and a bigger set (my_set). I want to overwrite the elements of the set with elements from the vector whenever they have the same type. Sounds simple:
struct update { update(my_set_type& to_overwrite_):to_overwrite(to_overwrite_){} template<typename T> void operator()(T& elt) /*const?*/ { boost::fusion::at_key<T>(to_overwrite)=elt; } my_set_type& to_overwrite; };
boost::fusion::for_each(my_vec,update(my_set));
Except that this won't compile because the operator() is required to be const, which is sad, because it was very simple.
And it won't compile *with* the const? I don't think the const'ness of the member function affects the const'ness of the referent of to_overwrite. That said, it does look the documentation for boost::fusion::for_each (indicating that F is received by value) contradicts the source code (where F is received by reference-to-const)... - Jeff

On 10/6/10 5:32 AM, Jeffrey Lee Hellrung, Jr. wrote:
On 10/05/2010 02:11 PM, Christophe Henry wrote:
Hi,
I have 2 fusion containers: a small vector (my_vec) and a bigger set (my_set). I want to overwrite the elements of the set with elements from the vector whenever they have the same type. Sounds simple:
struct update { update(my_set_type& to_overwrite_):to_overwrite(to_overwrite_){} template<typename T> void operator()(T& elt) /*const?*/ { boost::fusion::at_key<T>(to_overwrite)=elt; } my_set_type& to_overwrite; };
boost::fusion::for_each(my_vec,update(my_set));
Except that this won't compile because the operator() is required to be const, which is sad, because it was very simple.
And it won't compile *with* the const? I don't think the const'ness of the member function affects the const'ness of the referent of to_overwrite.
That said, it does look the documentation for boost::fusion::for_each (indicating that F is received by value) contradicts the source code (where F is received by reference-to-const)...
Jeffrey, I don't see that here (F is received by value): http://tinyurl.com/2vdao6r. Do you? Henry, could you provide some code I can try? const should be OK and I don't see any reason why not. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

On 10/05/2010 04:41 PM, Joel de Guzman wrote:
On 10/6/10 5:32 AM, Jeffrey Lee Hellrung, Jr. wrote: [...]
That said, it does look the documentation for boost::fusion::for_each (indicating that F is received by value) contradicts the source code (where F is received by reference-to-const)...
Jeffrey, I don't see that here (F is received by value): http://tinyurl.com/2vdao6r. Do you?
Hmmm...that looks difference from http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/algorithm/i... ??? - Jeff

On 10/6/10 8:01 AM, Jeffrey Lee Hellrung, Jr. wrote:
On 10/05/2010 04:41 PM, Joel de Guzman wrote:
On 10/6/10 5:32 AM, Jeffrey Lee Hellrung, Jr. wrote: [...]
That said, it does look the documentation for boost::fusion::for_each (indicating that F is received by value) contradicts the source code (where F is received by reference-to-const)...
Jeffrey, I don't see that here (F is received by value): http://tinyurl.com/2vdao6r. Do you?
Hmmm...that looks difference from
http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/algorithm/i...
Something must've changed. Christopher? Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Joel de Guzman schrieb:
On 10/6/10 8:01 AM, Jeffrey Lee Hellrung, Jr. wrote:
On 10/05/2010 04:41 PM, Joel de Guzman wrote:
On 10/6/10 5:32 AM, Jeffrey Lee Hellrung, Jr. wrote: [...]
That said, it does look the documentation for boost::fusion::for_each (indicating that F is received by value) contradicts the source code (where F is received by reference-to-const)...
Jeffrey, I don't see that here (F is received by value): http://tinyurl.com/2vdao6r. Do you?
Hmmm...that looks difference from
http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/algorithm/i...
Something must've changed. Christopher?
It wasn't me. In fact, the file hasn't been changed for three years: https://svn.boost.org/trac/boost/log/trunk/boost/fusion/algorithm/iteration/... Anyway, the functor should be passed by value. Let me quote Tobias (Schwinger) here, from an email from the 29th of October 2009 - in which he talks about passing by reference vs. passing by value in the functional subset of Fusion:
The target function is accepted by value - as the default. The functions are designed in a way that allows reference types to be used by explicitly specifying the template parameter 'Function'.
The reasons for the default were:
1. C++98-References and built-in function types do not mix well. There is a clause in the Standard rendering the program ill-formed as soon as a const qualifier gets added. There's a defect report about the issue and compiler-specific behavior may vary.
Example:
void a_func(); template< typename F > void take_func(F const&); take_func(a_func); // might or might not work
2. Consistency with existing practice, just look at the standard lib's <algorithm> header, for instance.
-Christopher

On 10/6/2010 6:22 PM, Christopher Schmidt wrote:
Joel de Guzman schrieb:
On 10/6/10 8:01 AM, Jeffrey Lee Hellrung, Jr. wrote:
On 10/05/2010 04:41 PM, Joel de Guzman wrote:
On 10/6/10 5:32 AM, Jeffrey Lee Hellrung, Jr. wrote: [...]
That said, it does look the documentation for boost::fusion::for_each (indicating that F is received by value) contradicts the source code (where F is received by reference-to-const)...
Jeffrey, I don't see that here (F is received by value): http://tinyurl.com/2vdao6r. Do you?
Hmmm...that looks difference from
http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/fusion/algorithm/i...
Something must've changed. Christopher?
It wasn't me. In fact, the file hasn't been changed for three years:
https://svn.boost.org/trac/boost/log/trunk/boost/fusion/algorithm/iteration/...
Anyway, the functor should be passed by value. Let me quote Tobias (Schwinger) here, from an email from the 29th of October 2009 - in which he talks about passing by reference vs. passing by value in the functional subset of Fusion:
The target function is accepted by value - as the default. The functions are designed in a way that allows reference types to be used by explicitly specifying the template parameter 'Function'.
The reasons for the default were:
1. C++98-References and built-in function types do not mix well. There is a clause in the Standard rendering the program ill-formed as soon as a const qualifier gets added. There's a defect report about the issue and compiler-specific behavior may vary.
Example:
void a_func(); template< typename F> void take_func(F const&); take_func(a_func); // might or might not work
2. Consistency with existing practice, just look at the standard lib's <algorithm> header, for instance.
That makes perfect sense. In that case, the code should reflect the docs. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net
participants (4)
-
Christophe Henry
-
Christopher Schmidt
-
Jeffrey Lee Hellrung, Jr.
-
Joel de Guzman