home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 32,330 of 33,346   
   =?UTF-8?B?RGFuaWVsIEtyw7xnbGVy?= to or function templates implied. Don'   
   Re: confused by template type parameter    
   24 May 12 12:56:25   
   
   6ee5d051   
   From: daniel.kruegler@googlemail.com   
      
   Am 24.05.2012 20:41, schrieb 萌 朱:   
   > The following simple program failed to compile with   
   > g++-4.7.0 -std=c++11   
   >   
   > // ex.1   
   > #include   
   > int main ()   
   > {   
   >   std::complex  const c(-1./2,sqrt(3.)/2);   
   >   std::complex  const d = std::pow(c,1./2);   
   >   return 0;   
   > }   
   >   
   > with "error: conversion from 'std::complex' to non-scalar   
   > type 'const std::complex' requested"   
      
   Let me nit-pick first that this program is already ill-formed because   
   there is no guarantee for the declaration of a function sqrt being   
   available. I'm adding an assumed   
      
   #include    
      
   > which I understand because the constructor of std::complex   
   > taking a std::complex  is explicit and I also know the   
   > workaround.   
      
   You are correct. Note also that in C++03 the function call   
   std::pow(c,1./2) would be ambiguous, because the compiler wouldn't find   
   a single best match for this overload set:   
      
   template complex pow(const complex&, int);   
   template complex pow(const complex&, const T&);   
   template complex pow(const complex&, const complex&);   
   template complex pow(const T&, const complex&);   
      
   Ignoring the last one, either of   
      
   template<> complex pow(const complex&, int);   
   template<> complex pow(const complex&, const float&);   
   template<> complex pow(const complex&, const   
   complex&);   
      
   would be considered and none (especially of the first two) is better   
   than the other compared to the arguments const std::complex and   
   double.   
      
   > What confused me is, it seems to me that the T parameter for   
   > std::pow is deduced as double, while I expect it to be deduced   
   > as float. Here is my logic.   
   >   
   > For ease of discussion, here are the overloads of std::pow   
   > involving a std::complex.   
   >   
   > template  complex  pow(const complex&, const T&);   
   > template  complex  pow(const complex&, const   
   > complex&);   
   > template  complex  pow(const T&, const complex&);   
   >   
   > For the first one, I expect T is deduced as float from c and   
   > double from 1./2, which then causes a deduction failure,   
   > so this one is gone. For the second one, T is deduced   
   > as float and it gets into the candidate set.   
   > The third one failed clearly.   
      
   Your deduction chain is wrong. First, if above overloads would be the   
   sole one existing, you would have a similar problem as in C++03, because   
   there would be no single best match and there would be an ambiguity   
   again. The solution for this is described in [cmplx.over] p3 of C++11,   
   where we have the following said:   
      
   "Function template pow shall have additional overloads sufficient to   
   ensure, for a call with at least one argument of type complex:   
      
   1. If either argument has type complex or type long double,   
   then both arguments are effectively cast to complex.   
   2. Otherwise, if either argument has type complex, double, or an   
   integer type, then both arguments are effectively cast to complex.   
   3. Otherwise, if either argument has type complex or float, then   
   both arguments are effectively cast to complex."   
      
   If you go though these bullets, the first match is bullet two, because   
   we have a second argument of type double. Therefore the code should   
   behave as if you would have called   
      
   std::pow(static_cast>(c),   
   static_cast>(1./2));   
      
   ending in the overload   
      
   template<> complex pow(const complex&, const   
   complex&);   
      
   > I then have the following slightly different program where I   
   > explicitly called std::pow specialized to float.   
   >   
   > // ex.2   
   > #include   
   > int main ()   
   > {   
   >   std::complex  const c(-1./2,sqrt(3.)/2);   
   >   std::complex  const d = std::pow(c,1./2);   
   >   return 0;   
   > }   
   >   
   > with g++-4.7.0 -std=c++11. Again, I got the same error message.   
   > This is even more confusing because I do not know how does the   
   > std::complex  type come into play in this call.   
   > I expect pow(complex  const&, float const&) is chosen   
   > and the second parameter binds to a temporary created from 1./2.   
   > The second version of pow is not favored because constructing   
   > a complex  from 1./2 involves a user-defined conversion.   
      
   The explicit template parameter does not solve the problem. In C++03 it   
   would still be ambiguous because of the three overloads   
      
   template<> complex pow(const complex&, int);   
   template<> complex pow(const complex&, const float&);   
   template<> complex pow(const complex&, const complex&);   
      
   In C++11 the code behaviour is unspecified, because from above wording   
   in [cmplx.over] p3 there is an unspecified number of further functions   
   or function templates implied. Don't write it that way in portable code.   
      
   > Moreover, if I compile ex.1 without the -std=c++11 flag using   
   > g++-4.7.0 (c++03 mode I assume).   
   > It is compiled ok, but running it shows that the d variable is   
   > computed to be (1,0) and the only reason I can think of is because   
   > the pow(const complex&,int) overload is called, which makes   
   > the 1./2 to be a 0 effectively. (btw, that overload is not in c++11)   
      
   IMO this behaviour is incorrect. In C++03 this should be ambigious as   
   explained above.   
      
   HTH & Greetings from Bremen,   
      
   Daniel Krügler   
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca