The code: class foo { public: template<typename T> foo(int i) : j(i) {} template<typename T> void bar(int i) { j = i; } template<typename T> static void baz(int i) {} int j; }; int main() { foo::baz<bool>(3); foo* p; p->bar<bool>(3); new foo<bool>(3); return 0; } gets you: ~/ootbc/chips$ g++ foo.cc foo.cc: In function âint main()â: foo.cc:8: error: âfooâ is not a template foo.cc:8: error: no matching function for call to âfoo::foo(int)â foo.cc:1: note: candidates are: foo::foo(const foo&) The constructor was declared as a template, and declaring other functions works OK. I can believe that parsing a templated constructor for a templated class is tough and so declaring templated constructors may be illegal. But if it is illegal to have templated constructors then the error should be flagged at the attempted declaration of one, rather than this peculiar message at the invocation site. But it looks to me like the parser hit the "<" in "foo<", saw that foo was not a template, and gave up before looking to see that the foo constructor *was* a template.
I don't think this is valid code. ICC also rejects the code. It is valid for template constuctor but not specify which templated constuctor you will call. foo is not a template so that error message is correct.
On further checking, you can have a templated constructor and invoke it - so long as it is fully resolved by the data arguments. You only get the diagnostic when the desired template has to be explicitly qualified. The compiler knows that qualification will be required because none of the function arguments depend on the template argument, so the template argument would have to be supplied explicitly and the declaration could be flagged at once (if this is in fact illegal) I think that the qualified invocation I reported is unambiguous, and certainly works for plain functions. But it's peculiar enough that both you and icc might have made the same mistake. Does the standard explicitly disallow this? If not then it should be accepted.
The standard does not provide to explicitly specify the template arguments of a constructor invocation. The syntax name<type> refers to a template class 'name' with template argument 'type', not to a template constructor 'name::name<type>'. This is just how the language works, nothing we can do about. W.
Yes, there IS something you can do about it. The compiler already checks whether a template is resolved by its data arguments (the message is something like "nothing of foo depends on any template argument and so ..."), so this construction can be and should be diagnosed at point of declaration of the constructor. Please reopen and change to a diagnostic issue. If for some reason the error cannot be diagnosed at the constructor, then fix the existing error messoge to something just a *bit* more enlightening :-) Ivan
Um, the error message says `foo' is not a template which is about as accurate as can be. That said, the request for a warning for constructors that can't be called is ok. Would you mind opening a new report only about this issue and closing the present one, so as to keep the audit trail of PRs as non-confusing as possible? Thanks W.
Done