Boost logo

Boost :

Subject: Re: [boost] [rpc] Introducing Boost.Reflect, Boost.CMT, and Boost.RPC
From: Daniel Larimer (dlarimer_at_[hidden])
Date: 2011-08-03 10:39:14


On Aug 3, 2011, at 7:02 AM, Julien Nitard wrote:

> Hi Daniel,
>
> Some more input on my usage of boost::reflect:
>
> - Annoying warning in reflect.hpp line 84 (multi-line comment), triggered
> because there's a back slash at the end of a single line comment. Removing
> the back slash or the line solves the problem. (I use -Wall).

I removed the line.

>
> - Additional facility to recurse:
> There are two cases where I think boost::reflect could add interesting
> functionality when visiting a type, for other types that are themselves
> reflected and for arrays.
> I wrote a visitor that converts the endianness of a reflected struct. When
> I browse an object, if the member is an array then I write special logic to
> apply the correction on array members and on members that are themselves
> reflected. In that special case I print a compilation error when a member's
> type is not reflected. A sample code is attached.
> I did something similar in my CSV visitor to output member arrays as Col1
> Col2 ... ColX (with an exception for char[] that is printed as a string).
>

A recursive visitor would require an instance of the type and would need to pass the 'this' pointer along with the member pointer and the name to the operator(). Earlier visions of the library had such an interface. I suppose it could be useful. In my primary 'test case', boost/rpc/json.hpp I also have to solve the recursive problem and I do it in a manner similar to your solution.

It would visit all of your data, but you would not know where/when a nested call began unless the visitor also
provided hooks. Perhaps it does not matter in your case (very interesting use case indeed!) I would like to include your code as an example, but unfortunately, it has other dependencies.

> - Remove the const in operator()
> The above example has a good reason to modify the data while recursing, that
> made declare my target object has mutable which I think is awkward. There
> could be two constructors to visitor one taking a const object and one
> taking a non-const object to keep the maximum const correctness when
> possible.

I didn't want it to be const, however, the options are either to pass by &, const &, or value. If I remove the const then my options are & or value. If I choose & then you cannot pass a temporary visitor as a parameter and if I choose value then I must create a copy of your visitor.

Ultimately I went with the const method because that is how boost::fusion visitors worked and if it is good enough for boost::fusion then it is good enough for me… right?

The only other alternative is to do a const_cast in reflector<T>::visit() before calling operator(). This would bypass the errors associated with passing a reference to a temporary, but violate people's expectations of a const& param.

A mutable reference makes no sense:

"The mutable specifier can be applied only to names of class data
members (9.2) and cannot be applied to names declared const or static,
and cannot be applied to reference members."

clang and maybe other compilers will complain if you create a mutable reference. I made that mistake myself. It should work if you simply remove the mutable keyword or replace the reference with a pointer. The pointer may be 'const', but what it points to will still be non-const. This still causes problems if you want to keep a counter or some other variable 'in the visitor', in that case, mutable seems to be the least-bad option.

Using rvalue references could be a solution if it c++0x was an option. Unfortunately, c++0x still rules out too many users.

Thanks for all the feedback, I am glad that you are finding the library so useful.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk