Topic: which template function?


Author: fvali@biotrack.com
Date: 1999/07/20
Raw View
Hi,
    Since your swap has a template parameter in the nested name
specifier, that parameter is used in a nondeduced context, and so it
will not be considered in the set of candidates.
Thus each time the swap( T&, T& ) should always be selected.


<snip>
> I also really want to support the syntax
>    std::swap(mi,mj);
> So if you have alternatives, then please tell me.
>

Try something similar to this:

#include <iostream>


template<typename TY_>
struct Matrix
{
  struct Row
  { typedef TY_ PType; }; // parametrized type
  Row row() { return Row(); }
};

template<typename TY_>
void choose( typename Matrix<TY_>::Row , typename Matrix<TY_>::Row )
{
  cout << "specialized choose called" << endl;
  // should never ever be selected via template argument deduction.
  // only through explicit specification of template arguments.
}

template<typename TY_>
void choose( TY_, TY_ )
{
  cout << "non-specialized one called" << endl;
}

template<typename TY_>
void choose( typename Matrix<typename TY_::PType>::Row , TY_  )
{
  cout << "specialized-hack choose called" << endl;
}


int main()
{
  Matrix<int> m;
  choose( m.row(), m.row() );
}


regards,
-fais


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/07/02
Raw View
Consider this code:

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

#include <iostream.h>

namespace myspace
{
   template <class T>
   struct matrix
   { public:
      typedef size_t size_type;
      class row_t { friend class matrix; row_t(){}; public: size_type size(); };
      row_t row(size_type) { return row_t(); }
   };
}

namespace std
{
   // 1st swap
   template <class T>
   void swap(T&, T&) { cout << "swap(T&,T&)\n"; }

   // 2nd swap
   template <class T>
   void swap(
      const typename myspace::matrix<T>::row_t&,
      const typename myspace::matrix<T>::row_t&
   ) { cout << "swap(const matrix::row_t&, const matrix::row_t&)\n"; }

   // 3rd swap
   template <class T>
   void swap(
      typename myspace::matrix<T>::row_t&,
      typename myspace::matrix<T>::row_t&
   ) { cout << "swap(matrix::row_t&, matrix::row_t&)\n"; }
}

int main()
{
   myspace::matrix<int> M;

   std::swap(M.row(0),M.row(1)); // call which swap? or syntax error?

   myspace::matrix<int>::row_t m0=M.row(0);
   myspace::matrix<int>::row_t m1=M.row(1);
   std::swap(m0,m1); // call which swap? or syntax error?
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

For
   std::swap(M.row(0),M.row(1)); // call which swap? or syntax error?
egcs and como (Comeau, an EDG compiler) try to call the first swap(T&,T&)
with T==matrix<int>::row_t, and give the error that we are passing
temporaries as non-const references.  However, I think that the compilers
should call the second swap.  Indeed, if I leave out the two 'typename'
keywords in the definition of the 2nd swap, then egcs calls the second
swap (sounds like a bug in the egcs compiler though).  So who is right?
Should the compiler call the first swap and then give a compile error
that we are passing temporaries as non-const, or should it just call the
second swap?

I really want to support the syntax
   std::swap(M.row(i),M.row(j));
So if you have alternatives, then please tell me.


For
   std::swap(m0,m1); // call which swap? or syntax error?
both egcs and como call the first swap, whereas I think they should
call the third.  If I comment out the first swap, then both compilers
give me the error that there is no function to call.  Evidently, they
are not even aware of the 2nd and 3rd swap.  So who is right?  Should
the compiler call the first swap or the third swap?

I also really want to support the syntax
   std::swap(mi,mj);
So if you have alternatives, then please tell me.

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]