This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
C++ : default template arguments for template specialization (was: Fix for bug 68)
- To: <gcc-bugs at gcc dot gnu dot org>
- Subject: C++ : default template arguments for template specialization (was: Fix for bug 68)
- From: "Artem Khodush" <kaa at comail dot ru>
- Date: Thu, 4 Jan 2001 04:11:38 +0300
Hi all,
This is for gcc-20001225.
There is something wrong with this patch:
2000-12-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
* pt.c (check_explicit_specialization): Propagate default
function arguments to explicit specializations.
http://gcc.gnu.org/ml/gcc-patches/2000-12/msg00616.html
+ /* Inherit default function arguments from the template
+ DECL is specializing. */
+ {
+ tree t1 = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ tree t2 = TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (tmpl)));
+
+ /* DECL may contain more parameters than TMPL due to the extra
+ in-charge parameter in constructors and destructors. */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2);
+ if (DECL_HAS_IN_CHARGE_PARM_P (decl))
+ t1 = TREE_CHAIN (t1);
+
+ /* Note that we do not need to reparse default arguments,
+ since explicit specialization cannot be declared in
+ class scope as in [temp.expl.spec]. */
+ for (; t1 && t2; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
+ {
+ if (TREE_PURPOSE (t2))
+ TREE_PURPOSE (t1) = TREE_PURPOSE (t2);
+ }
+
+ my_friendly_assert (t1 == NULL_TREE && t2 == NULL_TREE, 20001211);
+ }
+
The testcase:
#include <vector>
#include <locale>
int main() {
std::vector< int > v;
}
now gives me unexpected error:
vect.cxx: In function `int main()':
vect.cxx:5: call of overloaded `vector()' is ambiguous
/tmp/BUILD/gcc-20001225/libstdc++-v3/include/bits/stl_vector.h:252: candidates
are: std::vector<_Tp, _Alloc>::vector(unsigned int = 0) [with _Tp = int,
_Alloc = std::allocator<int>]
/tmp/BUILD/gcc-20001225/libstdc++-v3/include/bits/stl_vector.h:244:
std::vector<_Tp, _Alloc>::vector(typename std::_Vector_base<_Tp,
_Alloc>::allocator_type& = typename std::_Vector_base<_Tp,
_Alloc>::allocator_type()) [with _Tp = int, _Alloc = std::allocator<int>]
Looking at the tree dump for the testcase, I see that argument type nodes for an unsigned
argument are shared between vector::vector(unsigned) and explicit instantiation for
messages_byname<char>::messages_byname(char const*, unsigned).
Apparently the code
+ if (TREE_PURPOSE (t2))
+ TREE_PURPOSE (t1) = TREE_PURPOSE (t2);
sets default argument value to all such shared tree nodes, so vector::vector(unsigned) now "inherits"
default value from the primary template for messages_byname::messages_byname(char const*, unsigned),
and becomes ambiguous with default vector constructor.
Hope this is useful,
Artem.