C++ function templates can be explicitly instantiated. Constructors can be function templates. So the following should compile (and indeed does with icc and Comeau C++) struct Y { template <typename T> Y (T); template <typename T> void foo (T); }; template <> void Y::foo (bool) { } template <> void Y::foo<int> (int) { } template <> Y::Y (bool) { } template <> Y::Y<int> (int) { } Explicit instantiation of Y::foo, but not Y::Y, is permitted. g++ gives these errors: (not only is g++ wrong to give an error, but the error message below contains the nonsensical "no member function `._0' declared") constructor-explicit-instantiation-bug.cc:11: `Y' is not a template constructor-explicit-instantiation-bug.cc:11: ISO C++ forbids declaration of ` type name' with no type constructor-explicit-instantiation-bug.cc:11: abstract declarator `int (Y::)(int)' used as declaration constructor-explicit-instantiation-bug.cc:11: no member function `._0' declared in `Y' constructor-explicit-instantiation-bug.cc:11: syntax error before `{' token Release: g++ 3.2.1 Environment: Linux x86 How-To-Repeat: Compile the provided fragment with "g++ -c"
State-Changed-From-To: open->analyzed State-Changed-Why: Confirmed.
it still happens in the mainline (20030525) but it produces different error message: [omni:~/src/gccPRs] pinskia% g++ pr9050.cc pr9050.cc:11: error: expected unqualified-id
This seems to be related to PR 10832.
The error message on mainline now is: bug.cc:11: error: `Y' is not a template bug.cc:11: error: expected unqualified-id before "int" bug.cc:11: error: expected `)' before "int" bug.cc:11: error: expected `;' before "int"
*** Bug 10832 has been marked as a duplicate of this bug. ***
Hi All, I've been working on a project for the last month or so and have ran into this bug under G++ 2.95.4. The code I have is different from the code above and is as follows: test.hxx template <class T> class Test { private: T *handle_object; public: Test(T * = NULL); Test(const Test<T> &); ~Test(); bool operator==(const Test<T> &) const; }; class MyTest; typedef Test<MyTest> MyTestHandle; Test.cxx: template <class T> Test<T>::Test(T* th) { this->handle_object = th; if (this->handle_object != NULL) { this->handle_object->counter++; } } template <class T> Test<T>::Test(const Test<T> &source) { this->handle_object = source.handle_object; if (this->handle_object != NULL) { this->handle_object->counter++; } } template <class T> Test<T>::~Test() { if (this->handle_object != NULL && this->handle_object->counter != 0) { this->handle_object->counter--; } if (this->handle_object != NULL && this->handle_object->counter == 0) { delete this->handle_object; this->handle_object = NULL; } } template <class T> bool Test<T>::operator==(const Test<T> &source) const { return (this->handle_object == source->handle_object); } When I left it in this format I got this error: test/libtest.a(MyBigTest.o): In function `MyBigTest::add(Test<MyTest> const &)': /usr/local/include/stlport/stl/_construct.h:237: undefined reference to `Test<MyTest>::Test(Test<MyTest> const &)' test/libtest.a(MyBigTest.o): In function `MyBigTest::remove(Test<MyTest> &)': /usr/local/include/stlport/stl/_list.h:122: undefined reference to `Test<MyTest>::operator==(Test<MyTest> const &) const' test/libtest.a(MyBigTest.o): In function `MyBigTest::remove(Test<MyTest> &)': /usr/local/include/stlport/stl/_construct.h:360: undefined reference to `Test<MyTest>::~Test(void)' test/libtest.a(MyBigTest.o): In function `_STL::allocator<Test<MyTest> >::~allocator(void)': /usr/local/include/stlport/stl/_alloc.h (.gnu.linkonce.t.clear__Q24_STLt10_List_base2Zt14Test1Z6MyTestZQ24_STLt9allocato r1Zt14Test1Z6MyTest+0x26): undefined reference to `Test<MyTest>::~Test(void)' *** Error code 1 Research showed that I needed to instantiate my template using: template void Test<MyTest>(); in the Test.cpp file so that it can create an instance in the libtest.a file, so that when I compile that into my app it would link properly. However, I now run into a compiler error (rather then a linking error) like this: Test.cxx:52: `Test<MyTest>' specified as declarator-id Test.cxx:52: two or more data types in declaration of `Test<MyTest>' Test.cxx:52: non-template used as template Test.cxx:52: confused by earlier errors, bailing out *** Error code 1 Which I believe is related to the issue above. I'm building under FreeBSD 4.10- STABLE. Does anyone have a fix for this yet? or did I do something wrong?
The problem in comment #6 has nothing to do with the rest of the PR. The syntax to explicitly instantiate the class is just completely bogus. It should read template class Test<MyTest>; but there are more bugs (specificly: MyTest is only forward declared). The original problem of this PR persists as of now. W.
This bug is present in gcc 3.4.3. Was ever fixed or forgotten forever?
(In reply to comment #8) > This bug is present in gcc 3.4.3. Was ever fixed or forgotten forever? manuel@gcc12:~$ ~/132202/build/gcc/cc1plus --version GNU C++ (GCC) version 4.3.0 20080209 (experimental) [trunk revision 132202] (x86_64-unknown-linux-gnu) compiled by GNU C version 4.3.0 20080209 (experimental) [trunk revision 132202], GMP version 4.2.2, MPFR version 2.3.0. GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 manuel@gcc12:~$ ~/132202/build/gcc/cc1plus src/pr9050.C void Y::foo(T) [with T = bool] void Y::foo(T) [with T = int] Y::Y(T) [with T = bool] Y::Y(T) [with T = bool] Y::Y(T) [with T = bool] src/pr9050.C: At global scope: src/pr9050.C:11: error: ‘Y’ is not a template src/pr9050.C:11: error: expected unqualified-id before ‘int’ src/pr9050.C:11: error: expected `)' before ‘int’ Not fixed.
It seems that the problem is cp_parser_template_id fails to parse Y<int> as a template-id because when it does a lookup it finds that Y is just a non-template class and concludes that Y<int> cannot be a template-id. This in turn makes cp_parser_class_name fail to parse Y<int>, which makes cp_parser_constructor_declarator_p return false. No idea how this could be fixed...
Subject: Bug 9050 Author: jason Date: Sat Nov 21 06:33:56 2009 New Revision: 154403 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=154403 Log: PR c++/9050, DR 147, DR 318 * parser.c (cp_parser_lookup_name): If the name matches the explicit class scope, we're naming the constructor. (cp_parser_constructor_declarator_p): Just use cp_parser_unqualified_id if we have a nested-name-specifier. (cp_parser_direct_declarator): Handle getting an overload set as a constructor declarator. (cp_parser_unqualified_id): Avoid looking up the constructor when naming the destructor. (cp_parser_diagnose_invalid_type_name): Give good diagnostic for improper use of constructor as template. * typeck.c (finish_class_member_access_expr): Give good diagnostic about calling constructor. * error.c (dump_aggr_type): Don't print A::A for injected-class-name. Added: trunk/gcc/testsuite/g++.dg/template/ctor9.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/error.c trunk/gcc/cp/parser.c trunk/gcc/cp/typeck.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/g++.dg/lookup/name-clash4.C trunk/gcc/testsuite/g++.dg/tc1/dr147.C trunk/gcc/testsuite/g++.old-deja/g++.jason/temporary5.C trunk/gcc/testsuite/g++.old-deja/g++.pt/ctor2.C
Fixed for 4.5.
Jason, does http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1435 not render the explicit specialization ill-formed for C++11TC1? It only allows a simple identifier, and not a template-id.
(In reply to comment #13) > Jason, does http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1435 > not render the explicit specialization ill-formed for C++11TC1? It only allows > a simple identifier, and not a template-id. FWIW I don't like the resolution of that issue. For a qualified-id, the injected-class-name is an excellent way for us to know when and when not we name a constructor, and it is entirely based on name-lookup rules; I don't see the need to dictate that in clause 12. Only for an unqualified-id, we actually need the rule to know when we declare a constructor. The allowed decl-specifiers in a constructor declaration can be stated separately.
(In reply to comment #14) Good point, I've pointed out the problem with the proposed resolution.
(In reply to comment #15) > (In reply to comment #14) > > Good point, I've pointed out the problem with the proposed resolution. Note that we currently have http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#581 open. Even when 12.1 would have allowed both the injected class name and it followed by template-arguments, the name lookup rules would never allow it to match the second condition because the injected class name would always have been translated to a name denoting the constructor instead of the class. So ultimately, 12.1 allowing the injected class name followed by template arguments could only be used in an unqualified-id constructor declaration in C++03.
*** Bug 260998 has been marked as a duplicate of this bug. *** Seen from the domain http://volichat.com Page where seen: http://volichat.com/adult-chat-rooms Marked for reference. Resolved as fixed @bugzilla.