Boost logo

Boost :

From: Joaquín Mª López Muñoz (joaquin_at_[hidden])
Date: 2005-02-17 07:13:45


Hi David, thanks for trying Boost.MultiIndex!

David Gruener ha escrito:

> Hello,
>
> i just started using the boost::multi_index_container and ran into some
> trouble. I'm using boost version 1.32.
> Well, i tried a slightly modified version of Example 6 ("complex searches
> and foreign keys"). This is the code:

[...]

> As one might see, the change i made is that the key get_name() of the
> car_manufacturer now comes from a base class called person.
> However, this code wont compile because the compiler argues that there is no
> '*' operator for car_manufactuerer. I found out that the problem is
> the handling with the so called chained pointers in the mem_fun structs.
>
> template<typename ChainedPtr>
> Type operator()(const ChainedPtr& x)const // [1]
> {
> return operator()(*x);
> }
>
> Type operator()(const Class& x)const // [2]
> {
> return (x.*PtrToMemberFunction)();
> }
>
> In the example the compiler calls [1] for car_manufacturer*, which seems
> right. After that, it can chose (among other methods) between [1] and [2]
> (Class = person) with argument type car_manufacturer and choses the better
> matching [1] with the followed error.

Yes, your analysis of the problem is correct.

>
> However, maybe things could be done better here. The mem_fun structs
> could be smart enogh to deal with classes derived from template argument
> Class. That means [2] should be called in the case of operator() with a
> "Class"-derived argument.
> I dont know much about metaprogramming, but the following diff
> for const_mem_fun (as an example) of file mem_fun.hpp seems to work
> with a compiler supporting full template specialisation at class scope.
> Unfortunately gcc up to 3.4 doesn't seem to support this, while icc 8.0
> does. I'm pretty sure there is a better sollution than mine, assumed
> that a "problem" even exists, which is my question to you. :]
>

[...]

> ------------------------------------------------------------------------------
>
> Would some type handling like this make sense?

Yep, it would make sense. I guess it can be probably simplified,
so as to not rely in full template specialisation at class scope.
Anyway, please keep reading.

>
> If not, whats the best way to use dervied member function
> of a (pointer)member of the container type as key?

This is an infortunate problem with pointers to members as template
arguments. The expression

const_mem_fun<Derived,int,&Base::get>

is not valid even though &Base::get is really an int (Derived::*)const().
However, there's a way out using the alternative
const_mem_fun_explicit. See the attached example. Funny thing is
that const_mem_fun_explicit was never meant to solve this kind of
problems :)

>
> If yes, are there similar issues in other extractors like
> member extractor?

member<> has the very same problem, and in this case there's no
alternative member_explicit<>. You can workaround this with a little
more typing than desireable. See the attached code for an example.

I guess I'll have to consider how to best approach the problem. I'm
reluctant to change the extractors as they
are relatively fragile for buggy compilers (MSVC++ 6.0) but will
think it over. Hope the attached workarounds serve your needs
in the meantime.

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo




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