c++/10619: [diagnostic] Error message for no matching function calls does not list explicitally-specified template arguments
giovannibajo@libero.it
giovannibajo@libero.it
Sun May 4 14:56:00 GMT 2003
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 <typename T>
struct is_class
{
typedef char yes;
typedef double no;
template <typename Q>
static yes func(void (Q::*)(void));
template <typename Q>
static no func(...);
enum { value = sizeof(func<T>(0)) == sizeof(yes) };
// due to another bug, in GCC currently you need:
// sizeof(is_class::template func<T>(0))
// to make the above line compile
};
struct Foo {}
is_class<int>::value; // 0
is_class<Foo>::value; // 1
--------------------------------------------------------
* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Anyway, I keep this PR open for another reason. Given the
following code snippet:
-----------------------------
template <typename T>
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
More information about the Gcc-bugs
mailing list