The following code: namespace Foo { template <typename T> struct Meow { }; } template <> struct Foo::Meow<int> { }; fails to compile with gcc 4.8 (tested with 20130224 snapshot). I believe this code should be accepted in C++11 mode as per [temp.expl.spec] p2: "An explicit specialization shall be declared in a namespace enclosing the specialized template." This is a relaxation of the C++03 wording: "An explicit specialization shall be declared in the namespace of which the template is a member". Recent versions of clang and MSVC compile the above code in C++11 mode.
I think this is http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#374
(In reply to comment #1) > I think this is > http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#374 Ah, I see. The code is accepted if a declaration (without definition) of the specialization is placed in the namespace. Didn't realize that.
(In reply to Nathan Ridge from comment #2) > (In reply to comment #1) > > I think this is > > http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#374 > > Ah, I see. The code is accepted if a declaration (without definition) of the > specialization is placed in the namespace. Didn't realize that. ?? That was the c++03 status, and the new wording ("or to a specialization thereof") relaxed this requirement. Has this been implemented?
*** Bug 63705 has been marked as a duplicate of this bug. ***
Two possible fixes: 1) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 2cf10f442f68..09a545496fa8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -785,8 +785,12 @@ check_specialization_namespace (tree tmpl) return true; else { - permerror (input_location, "specialization of %qD in different namespace", tmpl); - permerror (input_location, " from definition of %q+#D", tmpl); + if (cxx_dialect < cxx11) + { + permerror (input_location, "specialization of %qD in different " + "namespace", tmpl); + permerror (input_location, " from definition of %q+#D", tmpl); + } return false; } } 2) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 2cf10f442f68..1171b5d736d5 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -780,15 +780,15 @@ check_specialization_namespace (tree tmpl) error ("specialization of %qD must appear at namespace scope", tmpl); return false; } - if (is_associated_namespace (current_namespace, tpl_ns)) - /* Same or super-using namespace. */ - return true; - else + if (!is_associated_namespace (current_namespace, tpl_ns) && + (cxx_dialect < cxx11)) { permerror (input_location, "specialization of %qD in different namespace", tmpl); permerror (input_location, " from definition of %q+#D", tmpl); return false; } + + return true; } /* SPEC is an explicit instantiation. Check that it is valid to The following testcases: g++.dg/template/spec17.C g++.dg/template/spec25.C g++.dg/template/spec36.C g++.old-deja/g++.ns/template13.C g++.old-deja/g++.pt/explicit73.C g++.old-deja/g++.pt/lookup10.C would have to be updated.
GCC 5.1 has been released.
GCC 5.2 is being released, adjusting target milestone to 5.3.
GCC 5.3 is being released, adjusting target milestone.
GCC 5.4 is being released, adjusting target milestone.
What an annoying bug, can this finally be fixed?! Our code base heavily relies on this feature alone as it's used in reflection code to specialize templates for certain types and it's done by expansion of preprocessor macro. This bug alone prevents us from using gcc as we heavily use this perfectly normal code: namespace NS1 { namespace NS2 { template<class T> int someFunction(); } } #define REGISTER(type) template<>NS1::NS2::someFunction<type>() { return something; } and then that REGISTER macro can be used in global namespace or inside NS1 or NS2.
Author: jason Date: Sun Nov 13 06:51:23 2016 New Revision: 242348 URL: https://gcc.gnu.org/viewcvs?rev=242348&root=gcc&view=rev Log: DR 374 - specialization in outer namespace PR c++/56840 * pt.c (check_specialization_namespace): Allow any enclosing namespace. (check_unqualified_spec_or_inst): New. (check_explicit_specialization): Call it. * parser.c (cp_parser_elaborated_type_specifier) (cp_parser_class_head): Call it. Added: trunk/gcc/testsuite/g++.dg/cpp0x/explicit-inst1.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-tree.h trunk/gcc/cp/decl.c trunk/gcc/cp/name-lookup.c trunk/gcc/cp/parser.c trunk/gcc/cp/pt.c
*** Bug 78274 has been marked as a duplicate of this bug. ***
*** Bug 60786 has been marked as a duplicate of this bug. ***
*** Bug 42018 has been marked as a duplicate of this bug. ***