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 31,980 of 33,346   
   =?ISO-8859-1?Q?Daniel_Kr=FCgler?= to All   
   Re: Function template argument deduction   
   03 Mar 12 01:04:38   
   
   203d4ad6   
   From: daniel.kruegler@googlemail.com   
      
   Am 02.03.2012 21:30, schrieb Cpp_Learner:   
   > Consider the code snippet below.   
   >   
   > The code snippet fails to compile with the error message "error: no   
   > matching function for call to 'beta(A*&)'" on gcc.   
      
   The compiler is correct.   
      
   > Given that "aA" is of the type "A::Aptr", I was expecting that   
   > the call "beta(aA)" will get resolved to the function template   
   > "template  void beta(typename A::Aptr a)", with "T" as   
   > "char".   
      
   No, the compiler cannot deduce *any* argument type from such a   
   construction. This is what the standard describes as a "non-deduced   
   context". The reason for this is, because templates can be specialized,   
   which means that the compiler cannot safely conclude what T is based on   
   some known type A::Aptr. You may think that this works, because you   
   only provided a single specialization (the primary template). But in   
   general, arbitrary specializations may be provided, e.g. consider   
      
   template<>   
   struct A   
   {   
     typedef bool* Aptr;   
   };   
      
   or   
      
   template<>   
   struct A   
   {   
     typedef void Aptr;   
   };   
      
   or anything else.   
      
   > I am kind of puzzled with this, and wanted to learn why the compiler   
   > is unable to resolve this. I do not see any issues if I modify the   
   > call site to beta(aA).   
      
   You don't see any issue here, because you explicitly provide the   
   template argument, thus the compiler just accepts the type. Given some   
   T, it can find the correct instantiation A, it sees that it has   
   the type A::Aptr of type A* - done.   
      
   > The snippet of code is related to some work I am doing on templatizing   
   > some old code to support additional types. I really would like to   
   > avoid this additional specification of template type at call site to   
   > keep things simple, and wanted to know if there are any workarounds   
   > that would not need me to modify the call sites.   
      
   You need a different strategy. E.g. you could add an inline friend in   
   template A:   
      
   template   
   struct A   
   {   
     typedef A  *Aptr;   
      
     friend void beta(Aptr a) { /**/ }   
   };   
      
   This works because such a friend function is considered as a   
   non-function template and thus there will be no argument type deduction   
   taking place (it works only if at least one function parameter depends   
   on A). A definition of a free function will only be created when beta is   
   odr-used.   
      
   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