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:

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::union_graph<ActualGraph1, ActualGraph2>
>::edge_descriptor a, b;

   // a, b assignment

   if ( operator!= <ActualGraph1, ActualGraph2>( a, b ) )

- 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?

Cosimo Calabrese.

Boost list run by bdawes at, gregod at, cpdaniel at, john at