From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23025 invoked by alias); 4 May 2003 14:44:57 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 23004 invoked by uid 48); 4 May 2003 14:44:57 -0000 Date: Sun, 04 May 2003 14:44:00 -0000 Message-ID: <20030504144457.23003.qmail@sources.redhat.com> To: gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org, gccbugs@contacts.eelis.net, giovannibajo@libero.it, nobody@gcc.gnu.org From: giovannibajo@libero.it Reply-To: giovannibajo@libero.it, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org, gccbugs@contacts.eelis.net, giovannibajo@libero.it, nobody@gcc.gnu.org, gcc-gnats@gcc.gnu.org Subject: Re: c++/10619: [diagnostic] Error message for no matching function calls does not list explicitally-specified template arguments X-SW-Source: 2003-05/txt/msg00235.txt.bz2 List-Id: Old Synopsis: Instantiation through function template return type causes too cryptic error. New Synopsis: [diagnostic] Error message for no matching function calls does not list explicitally-specified template arguments State-Changed-From-To: open->analyzed State-Changed-By: bajo State-Changed-When: Sun May 4 14:44:57 2003 State-Changed-Why: Your understanding of what the compiler does are wrong. When template functions are found during the lookup phase, the compiler _tries_ to specialize them, following several rules: it tries to deduce the template parameters from the arguments passed and/or uses the explicitally specified template parameters. If the deduction fails and/or is not possible to specialize the function in a way that would match the call, the function is _not_ instantiated _and_ it is not added to the overload set (which will be used later to decide which function must be called). De-legalizing the above, in your case, what happens is that the compiler detects that it is impossible to specialize f() in a way which would match a call like "f<0>()," because specializing with I=0 leads to a type error in the return type. Thus, the template function f() is not added to the overload set. Since there are no more functions called f(), the overload set ends up being empty, and the compiler correctly complains that there are no matching functions for call to f(). This is actually a feature of the language: you can use type deduction together with overload as a way to detect valid constructs. A quick example is the common is_class template trick, which uses deduction and overload to detect a class: the trick is that a class is an entity T for which declaring a pointer such as "void (T::*)(void)" is a valid construct: -------------------------------------------------------- template struct is_class { typedef char yes; typedef double no; template static yes func(void (Q::*)(void)); template static no func(...); enum { value = sizeof(func(0)) == sizeof(yes) }; // due to another bug, in GCC currently you need: // sizeof(is_class::template func(0)) // to make the above line compile }; struct Foo {} is_class::value; // 0 is_class::value; // 1 -------------------------------------------------------- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Anyway, I keep this PR open for another reason. Given the following code snippet: ----------------------------- template void foo(int ); int main() { foo<0>(4); } ----------------------------- pr10619.cpp: In function `int main()': pr10619.cpp:8: error: no matching function for call to `foo(int)' The error message is slightly wrong. It's not true that there are no matching calls "foo(int)". The problem here is that there are no matching calls for "foo<0>(int)". The error message does not list the explicitally specified template argument, which is the real problem for the call to fail. I think that the error message should rather be: "no matching function for call to foo<0>(int)" Then, I keep this as a change request for diagnostic. http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=10619