Boost logo

Boost :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2004-04-08 07:56:55


Hi Thorsten,

>> insert_assigner_with_functor< function< void (string) > >
>> add_cc(const string& s)
>> {
>> insert_assigner_with_functor< function< void(string> > > r(
>> bind(this, &Email::add_cc));
>>
>> r(s);
>> return r;
>> }
>
> This is something you could use in your program options, right?

Yes, I'm thinking about that.

> I'll have to think more about it, but wouldn't this work:
>
> insert_assigner< Email >
> add_cc( const string& s )
> {
> return insert< Email::add_cc >( *this )( s );
> }
>
> (given averything I haven't thought about works :-))

The insert_assigner< Email > still have to somehow store the functor... so
it somehow should know about the type of the stored functor, either because
the type is template parameter, or because insert_assigner stores a
boost::function which knows the type.

I've used boost::function in the previous post just because I can't guess
the type of bind(this, &Email::add_cc) ;-)

>> In fact,
>>
>> using assignment::operator<<
>>
>> does not have this problem, though it's cumbersome.
>
> it had with my compilers.

Hmm... strictly speaking,

   using assignment::operator<<;

should make this operator because as if it's declared in namespace where
"using" appears, as far as name hiding is concerned.

>>
>> A member function may be defined in its class definition, in which
>> case
> it
>> is an inline member function.
>>
>> So defining a function inside class has the same effect as "inline"
> specifier.
>
> true, but the compiler is not forced to inline it. So unless you are
> talking about
> requiring linking, I don't get it.

The point is: making the function 'inline', either with explicit keyword or
by placing it in the class body *increases* the chances that it will be
inlined. And since inlining here can cause code bloat, it's better not to
increase those chances.

I've just sketched an example which can be found at

   http://zigzag.cs.msu.su:7813/inline

There are two files -- one with in-class definition and one with
out-of-class definition. Both are compiled with -O3 but the function is
inlined only in the first example and the number of instructions needed to
each call grows from 4 to 13. In a real example the difference might be
smaller, but it also might be larger :-(

Some time ago, I was rather shocked to find that declaring a single option
in program_options took something about 1K of code size. So you'd get 100K
for 100 options, which is plain unacceptable. I solved that problem by
chaning some parameter types from std::string to char* to avoid implicit
conversion.

It was some time ago, so situation might have improved in gcc or in
libstdc++, but generally, unnecessary inlining will still increase the code
size.

>> Ok, let me try from a different perspective: when instances of this class
> are
>> created? At least the documentation does not say they are created
> anywhere...
>
> I agree it is not explained; when you call insert() for adjacency_list it
> will return such an instance.

Then I can only suggest that it's documented somehow. As it stands
tuple_insert_assigner looks like a component which is totally unrelated to
the rest of the library.

- Volodya


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