
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.