Topic: Defect Report: Nondeduced contexts


Author: iltchenko@yahoo.com (Andrei Iltchenko)
Date: 29 Apr 02 12:55:48 GMT
Raw View
 [Moderator's note: this defect report has been
 forwarded to the C++ committee. -moderator.]

Section: 14.8.2.1 - Deducing template arguments from a function call
[temp.deduct.call]
Submitter: Andrei Iltchenko (iltchenko@yahoo.com)

The current definition of the C++ language speaks about nondeduced
contexts only in terms of deducing template arguments from a type
14.8.2.4 [temp.deduct.type] paragraph 4. Those cases, however, don't
seem to be the only ones when template argument deduction is not
possible. The example below illustrates that:

namespace  A  {
   enum  ae  {   };
   template<class R, class A>
   int  foo(ae, R(*)(A))
   {   return  1;   }
}

template<typename T>
void  tfoo(T)
{   }

template<typename T>
int  tfoo(T)
{   return  1;   }

/*int  tfoo(int)
{   return  1;   }*/


int  main()
{
   A::ae   a;
   foo(a, &tfoo);
}

Here argument-dependent name lookup finds the function template
'A::foo' as a candidate function. None of the function template's
function parameter types constitutes a nondeduced context as per
14.8.2.4 [temp.deduct.type] paragraph 4. And yet, quite clearly,
argument deduction is not possible in this context. Furthermore it is
not clear what a conforming implementation shall do when the
definition of the non-template function '::tfoo' is uncommented.


Suggested resolution:

Add the following as a new paragraph immediately before paragraph 3 of
14.8.2.1 [temp.deduct.call]:

After the above transformations, in the event of P being a function
type, a pointer to function type, or a pointer to member function type
and the corresponding A designating a set of overloaded (member)
functions with at least one of the (member) functions introduced by
the use of a (member) function template name (13.4) or by the use of a
conversion function template (14.8.2.3), the whole function call
expression is considered to be a nondeduced context. [Example:

namespace  A  {
   enum  ae  {   };
   template<class R, class A>
   int  foo(ae, R(*)(A))
   {   return  1;   }
}

template<typename T>
void  tfoo(T)
{   }

template<typename T>
int  tfoo(T)
{   return  1;   }

int  tfoo(int)
{   return  1;   }

int  main()
{
   A::ae   a;
   foo(a, &tfoo);   //  ill-formed, the call is a nondeduced context
   using  A::foo;
   foo<void,int>(a, &tfoo);  // well-formed, the address of the spe-
                             // cialization 'void tfoo<int>(int)' is
                             // the second argument of the call
}


Regards,

Andrei Iltchenko.
---
[ 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://www.research.att.com/~austern/csc/faq.html                ]