Boost logo

Boost :

Subject: Re: [boost] [Variant] [BGL] Variant<edge_descriptor, edge_descriptor> is not EqualityComparable
From: Cosimo Calabrese (cosimo.calabrese_at_[hidden])
Date: 2009-11-15 16:03:22


Stefan Strasser ha scritto:
> Am Thursday 12 November 2009 15:00:09 schrieb Cosimo Calabrese:
>
>> namespace std
>> {
>> template <typename Graph1, typename Graph2>
>> std::ostream& operator<<(std::ostream& os,
>> const typename boost::graph_traits<boost::union_graph<Graph1, Graph2>
>>
>> >::vertex_descriptor& v)
>>
>> {
>> if ( boost::get<WR1<graph_traits<Graph1>::vertex_descriptor> >( &v ) )
>> os <<
>> boost::get<WR1<graph_traits<Graph1>::vertex_descriptor>
>>
>> >(v)._data;
>>
>> else
>> os <<
>> boost::get<WR2<graph_traits<Graph2>::vertex_descriptor> >(v)._data;
>> return os;
>> }
>> }
>
> the template parameters (Graph1/2) must be deducable from the function
> parameter (v).
> this is not possible in this example.
>
> consider the following, simpler, case:
> template<class T>
> struct A{
> typedef T type;
> };
>
> template<class A_T>
> void func(typename A_T::type);
>
> int main(){
> int a;
> func<A<int> >(); //ok
> func(a); //error
> }
>
> the compiler has no way of knowing that foo is supposed to be instantiated
> with A_T == A, unless you provide an explicit template argument (which you
> don't when you call an operator).
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>

Sorry for late, but I have had to think on a little...

So, IIUC there is a concept required by the A_T type, that is A_T must
has a "child" type (A_T::type). The argument of func is the "child" of
A_T. It's crucial to know which is the actual A_T type to istantiate the
correct func version. So, if I explicitly specify the template
parameter, e.g.:

   func<A<int> >(...);

so the correct func version is istantiated, and this specifies that the
func actual argument is an int.
But if I don't specify the template param and pass an int as argument,
the compiler can't know which is the parent of that int.
I've tried to create a variable of type:

   A<int>::type obj;

and pass it to func, but the compiler can't deduce the template
argument; perhaps obj is just an int, and the fact that the int is a
A<int>::type is ignored.

So the error in my case is not in the prototype declaration of
operator<<() or operator!=(); the error is in the call of operators. To
call correctly the operators I should (theoretically) call:

   boost::graph_traits<
     boost::union_graph<ActualGraph1, ActualGraph2>
>::edge_descriptor a, b;

   // a, b assignment

   if ( operator!= <ActualGraph1, ActualGraph2>( a, b ) )
   {
     //...
   }

but:
- it's illeagal;
- a generic algorithm that applies operator!=() can't know the actual
type of Graph1 and Graph2.

Is it correct?

So, is the problem originated by the fact that the function argument is
a "child" of the template param type?

And in my case, the only thing I can do is avoid this? Like:

template <typename T1, typename T2>
bool operator!=( boost::variant<boost::WR1<T1>, boost::WR2<T2> >& left,
                  boost::variant<boost::WR1<T1>, boost::WR2<T2> >& right)
{
     return !( left == right );
}

in that WR1<T1> is not a "child" of T1, but an actual type that depends
by T1?

Thanks,
Cosimo Calabrese.


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