one thing that bugs me about c++

Neal Becker ndbecker2 at gmail.com
Thu Dec 13 17:45:13 PST 2007


Sean Kelly wrote:

> Neal Becker wrote:
>> In c++,
>> 
>> template<typename T>
>> void F (T);
>> 
>> template<typename T>
>> void F (std::complex<T>);
>> 
>> This doesn't work. I want the second overload to be the 'best' match for
>> 
>> F (std::complex<double>)
>> 
>> for example, but the standard doesn't agree.
>> 
>> Never really made sense to me.  What would D do?
> 
> Seems I need to brush up on my knowledge of template overload
> resolution, as I'd expect the second overload to be chosen for the
> reason you provide.  Still, perhaps it isn't truly "more specialized"
> because in each case a T is being substituted into the one parameter?
> I'll give the C++ spec a gander on my way home and see if I can come up
> with anything more enlightening.
> 
> 
Ouch, I had oversimplified the problem.  The above does compile.  OK, here
is the _real_ problem:
--------------------
#include <complex>
#include <vector>

using namespace std;

template<typename T>
T mag_sqr1 (T z) { return z * z; }

template<typename T>
T mag_sqr1 (complex<T> z) { return real(z)*real(z) + imag(z)*imag(z); }

template<typename T>
struct scalar { typedef T type; };

template<typename T>
struct scalar<complex<T> > { typedef T type; };


template<typename T>
inline vector<typename scalar<T>::type> mag_sqr (vector<T> const& z) {
  typedef typename scalar<T>::type out_t;
  vector<out_t> out (z.size());
  std::transform (z.begin(), z.end(), out.begin(), mag_sqr1<T>);
  return out;
}

int main () {
  vector<complex<double> > v;
  mag_sqr (v);
}
------------------
test1.cc:29:   instantiated from here
test1.cc:23: error: no matching function for call
to ‘transform(__gnu_cxx::__normal_iterator<const std::complex<double>*,
std::vector<std::complex<double>, std::allocator<std::complex<double> > >
>, __gnu_cxx::__normal_iterator<const std::complex<double>*,
std::vector<std::complex<double>, std::allocator<std::complex<double> > >
>, __gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double> > >, <unresolved overloaded function type>)’

But if we change the mag_sqr1 from overloaded functions to functors, this
compiles fine.  (and change the call to:
std::transform (z.begin(), z.end(), out.begin(), mag_sqr1<T>())
)



More information about the Digitalmars-d mailing list