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. From-SVN: r242348
This commit is contained in:
parent
478eca6464
commit
ba1e69c03f
28 changed files with 190 additions and 132 deletions
|
@ -1,3 +1,14 @@
|
|||
2016-11-12 Jason Merrill <jason@redhat.com>
|
||||
|
||||
DR 374
|
||||
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.
|
||||
|
||||
2016-11-10 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/77337
|
||||
|
|
|
@ -6082,6 +6082,7 @@ extern void reset_specialization (void);
|
|||
extern void end_specialization (void);
|
||||
extern void begin_explicit_instantiation (void);
|
||||
extern void end_explicit_instantiation (void);
|
||||
extern void check_unqualified_spec_or_inst (tree, location_t);
|
||||
extern tree check_explicit_specialization (tree, tree, int, int);
|
||||
extern int num_template_headers_for_class (tree);
|
||||
extern void check_template_variable (tree);
|
||||
|
|
|
@ -7868,8 +7868,7 @@ check_class_member_definition_namespace (tree decl)
|
|||
diagnostics. */
|
||||
if (processing_specialization)
|
||||
return;
|
||||
/* There are no restrictions on the placement of
|
||||
explicit instantiations. */
|
||||
/* We check this in check_explicit_instantiation_namespace. */
|
||||
if (processing_explicit_instantiation)
|
||||
return;
|
||||
/* [class.mfct]
|
||||
|
|
|
@ -3558,7 +3558,7 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
|
|||
/* Since decl is a function, old should contain a function decl. */
|
||||
if (!is_overloaded_fn (old))
|
||||
goto complain;
|
||||
/* A template can be explicitly specialized in any namespace. */
|
||||
/* We handle these in check_explicit_instantiation_namespace. */
|
||||
if (processing_explicit_instantiation)
|
||||
return;
|
||||
if (processing_template_decl || processing_specialization)
|
||||
|
|
|
@ -17004,24 +17004,28 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
|
|||
globalscope = cp_parser_global_scope_opt (parser,
|
||||
/*current_scope_valid_p=*/false);
|
||||
/* Look for the nested-name-specifier. */
|
||||
tree nested_name_specifier;
|
||||
if (tag_type == typename_type && !globalscope)
|
||||
{
|
||||
if (!cp_parser_nested_name_specifier (parser,
|
||||
nested_name_specifier
|
||||
= cp_parser_nested_name_specifier (parser,
|
||||
/*typename_keyword_p=*/true,
|
||||
/*check_dependency_p=*/true,
|
||||
/*type_p=*/true,
|
||||
is_declaration))
|
||||
is_declaration);
|
||||
if (!nested_name_specifier)
|
||||
return error_mark_node;
|
||||
}
|
||||
else
|
||||
/* Even though `typename' is not present, the proposed resolution
|
||||
to Core Issue 180 says that in `class A<T>::B', `B' should be
|
||||
considered a type-name, even if `A<T>' is dependent. */
|
||||
cp_parser_nested_name_specifier_opt (parser,
|
||||
/*typename_keyword_p=*/true,
|
||||
/*check_dependency_p=*/true,
|
||||
/*type_p=*/true,
|
||||
is_declaration);
|
||||
nested_name_specifier
|
||||
= cp_parser_nested_name_specifier_opt (parser,
|
||||
/*typename_keyword_p=*/true,
|
||||
/*check_dependency_p=*/true,
|
||||
/*type_p=*/true,
|
||||
is_declaration);
|
||||
/* For everything but enumeration types, consider a template-id.
|
||||
For an enumeration type, consider only a plain identifier. */
|
||||
if (tag_type != enum_type)
|
||||
|
@ -17069,8 +17073,18 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
|
|||
else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL)
|
||||
;
|
||||
else if (TREE_CODE (decl) == TYPE_DECL)
|
||||
type = check_elaborated_type_specifier (tag_type, decl,
|
||||
/*allow_template_p=*/true);
|
||||
{
|
||||
type = check_elaborated_type_specifier (tag_type, decl,
|
||||
/*allow_template_p=*/true);
|
||||
|
||||
/* If the next token is a semicolon, this must be a specialization,
|
||||
instantiation, or friend declaration. Check the scope while we
|
||||
still know whether or not we had a nested-name-specifier. */
|
||||
if (type != error_mark_node
|
||||
&& !nested_name_specifier && !is_friend
|
||||
&& cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
|
||||
check_unqualified_spec_or_inst (type, token->location);
|
||||
}
|
||||
else if (decl == error_mark_node)
|
||||
type = error_mark_node;
|
||||
}
|
||||
|
@ -22336,6 +22350,11 @@ cp_parser_class_head (cp_parser* parser,
|
|||
{
|
||||
type = TREE_TYPE (id);
|
||||
type = maybe_process_partial_specialization (type);
|
||||
|
||||
/* Check the scope while we still know whether or not we had a
|
||||
nested-name-specifier. */
|
||||
if (type != error_mark_node)
|
||||
check_unqualified_spec_or_inst (type, type_start_token->location);
|
||||
}
|
||||
if (nested_name_specifier)
|
||||
pushed_scope = push_scope (nested_name_specifier);
|
||||
|
|
67
gcc/cp/pt.c
67
gcc/cp/pt.c
|
@ -772,28 +772,29 @@ check_specialization_namespace (tree tmpl)
|
|||
|
||||
/* [tmpl.expl.spec]
|
||||
|
||||
An explicit specialization shall be declared in the namespace of
|
||||
which the template is a member, or, for member templates, in the
|
||||
namespace of which the enclosing class or enclosing class
|
||||
template is a member. An explicit specialization of a member
|
||||
function, member class or static data member of a class template
|
||||
shall be declared in the namespace of which the class template is
|
||||
a member. */
|
||||
An explicit specialization shall be declared in a namespace enclosing the
|
||||
specialized template. An explicit specialization whose declarator-id is
|
||||
not qualified shall be declared in the nearest enclosing namespace of the
|
||||
template, or, if the namespace is inline (7.3.1), any namespace from its
|
||||
enclosing namespace set. */
|
||||
if (current_scope() != DECL_CONTEXT (tmpl)
|
||||
&& !at_namespace_scope_p ())
|
||||
{
|
||||
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. */
|
||||
|
||||
if (cxx_dialect < cxx11
|
||||
? is_associated_namespace (current_namespace, tpl_ns)
|
||||
: is_ancestor (current_namespace, tpl_ns))
|
||||
/* Same or enclosing namespace. */
|
||||
return true;
|
||||
else
|
||||
{
|
||||
permerror (input_location,
|
||||
"specialization of %qD in different namespace", tmpl);
|
||||
permerror (DECL_SOURCE_LOCATION (tmpl),
|
||||
" from definition of %q#D", tmpl);
|
||||
inform (DECL_SOURCE_LOCATION (tmpl),
|
||||
" from definition of %q#D", tmpl);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2586,6 +2587,36 @@ check_template_variable (tree decl)
|
|||
}
|
||||
}
|
||||
|
||||
/* An explicit specialization whose declarator-id or class-head-name is not
|
||||
qualified shall be declared in the nearest enclosing namespace of the
|
||||
template, or, if the namespace is inline (7.3.1), any namespace from its
|
||||
enclosing namespace set.
|
||||
|
||||
If the name declared in the explicit instantiation is an unqualified name,
|
||||
the explicit instantiation shall appear in the namespace where its template
|
||||
is declared or, if that namespace is inline (7.3.1), any namespace from its
|
||||
enclosing namespace set. */
|
||||
|
||||
void
|
||||
check_unqualified_spec_or_inst (tree t, location_t loc)
|
||||
{
|
||||
tree tmpl = most_general_template (t);
|
||||
if (DECL_NAMESPACE_SCOPE_P (tmpl)
|
||||
&& !is_associated_namespace (current_namespace,
|
||||
CP_DECL_CONTEXT (tmpl)))
|
||||
{
|
||||
if (processing_specialization)
|
||||
permerror (loc, "explicit specialization of %qD outside its "
|
||||
"namespace must use a nested-name-specifier", tmpl);
|
||||
else if (processing_explicit_instantiation
|
||||
&& cxx_dialect >= cxx11)
|
||||
/* This was allowed in C++98, so only pedwarn. */
|
||||
pedwarn (loc, OPT_Wpedantic, "explicit instantiation of %qD "
|
||||
"outside its namespace must use a nested-name-"
|
||||
"specifier", tmpl);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check to see if the function just declared, as indicated in
|
||||
DECLARATOR, and in DECL, is a specialization of a function
|
||||
template. We may also discover that the declaration is an explicit
|
||||
|
@ -2949,15 +2980,8 @@ check_explicit_specialization (tree declarator,
|
|||
return error_mark_node;
|
||||
else
|
||||
{
|
||||
if (!ctype && !was_template_id
|
||||
&& (specialization || member_specialization
|
||||
|| explicit_instantiation)
|
||||
&& !is_associated_namespace (CP_DECL_CONTEXT (decl),
|
||||
CP_DECL_CONTEXT (tmpl)))
|
||||
error ("%qD is not declared in %qD",
|
||||
tmpl, current_namespace);
|
||||
else if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_HIDDEN_FRIEND_P (tmpl))
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_HIDDEN_FRIEND_P (tmpl))
|
||||
{
|
||||
if (pedwarn (DECL_SOURCE_LOCATION (decl), 0,
|
||||
"friend declaration %qD is not visible to "
|
||||
|
@ -2965,6 +2989,9 @@ check_explicit_specialization (tree declarator,
|
|||
inform (DECL_SOURCE_LOCATION (tmpl),
|
||||
"friend declaration here");
|
||||
}
|
||||
else if (!ctype && !is_friend
|
||||
&& CP_DECL_CONTEXT (decl) == current_namespace)
|
||||
check_unqualified_spec_or_inst (tmpl, DECL_SOURCE_LOCATION (decl));
|
||||
|
||||
tree gen_tmpl = most_general_template (tmpl);
|
||||
|
||||
|
|
13
gcc/testsuite/g++.dg/cpp0x/explicit-inst1.C
Normal file
13
gcc/testsuite/g++.dg/cpp0x/explicit-inst1.C
Normal file
|
@ -0,0 +1,13 @@
|
|||
// In C++11 explicit instantiation without a nested-name-specifier must be in
|
||||
// the same namespace.
|
||||
|
||||
namespace N {
|
||||
template <class T> class foo {};
|
||||
template <class T> class bar {};
|
||||
}
|
||||
|
||||
using N::bar;
|
||||
template class bar<int>; // { dg-error "" "" { target c++11 } }
|
||||
|
||||
using namespace N;
|
||||
template class foo<int>; // { dg-error "" "" { target c++11 } }
|
|
@ -1,7 +1,7 @@
|
|||
// PR c++/16224
|
||||
|
||||
namespace io {
|
||||
template <typename> int foo(); // { dg-error "" }
|
||||
template <typename> int foo();
|
||||
}
|
||||
|
||||
using namespace io;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
namespace N {
|
||||
template <typename T>
|
||||
struct S {
|
||||
void f() {} // { dg-error "definition" }
|
||||
void f() {}
|
||||
};
|
||||
}
|
||||
|
||||
namespace K {
|
||||
template <> void N::S<char>::f() {} // { dg-error "different namespace" }
|
||||
template <> void N::S<char>::f() {} // { dg-error "namespace" }
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ struct basic_string
|
|||
namespace MyNS {
|
||||
class MyClass {
|
||||
template <typename T>
|
||||
T test() { } /* { dg-error "from definition" } */
|
||||
T test() { } /* { dg-message "from definition" "" { target c++98_only } } */
|
||||
};
|
||||
}
|
||||
template <>
|
||||
basic_string MyNS::MyClass::test() /* { dg-error "specialization of" } */
|
||||
basic_string MyNS::MyClass::test() /* { dg-error "specialization of" "" { target c++98_only } }*/
|
||||
{ return 1; }
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace bar
|
|||
{
|
||||
// trick it to provide some prior declaration
|
||||
template<class T>
|
||||
void foo(); // { dg-error "definition" }
|
||||
void foo();
|
||||
template<class T>class X; // { dg-message "note: previous declaration" }
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ bar::foo(T const &a) // { dg-error "" "" { xfail *-*-* } } not declared in b
|
|||
return a;
|
||||
}
|
||||
|
||||
template<> void bar::foo<int>() // { dg-error "different namespace" }
|
||||
template<> void bar::foo<int>() // { dg-error "different namespace" "" { target c++98_only } }
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// the template
|
||||
|
||||
namespace N {
|
||||
template <class T> class foo; // { dg-error "" } referenced below
|
||||
template <class T> class foo;
|
||||
}
|
||||
|
||||
using namespace N;
|
||||
|
|
|
@ -13,8 +13,8 @@ namespace Outer {
|
|||
namespace Core = Core_Real;
|
||||
|
||||
namespace Core_Real {
|
||||
template<class T> void Foo (T *) {} // { dg-error "definition" }
|
||||
template<class T> void Foo (T *) {}
|
||||
}
|
||||
|
||||
template<> void Core::Foo<> (Render_Real::Type *) {} // { dg-error "" }
|
||||
template<> void Core::Foo<> (Render_Real::Type *) {} // { dg-error "" "" { target c++98_only } }
|
||||
}
|
||||
|
|
|
@ -25,9 +25,8 @@
|
|||
#include <testsuite_tr1.h>
|
||||
|
||||
using namespace __gnu_test;
|
||||
using std::future;
|
||||
template class future<int>;
|
||||
template class future<int&>;
|
||||
template class future<void>;
|
||||
template class future<ClassType>;
|
||||
template class future<ClassType&>;
|
||||
template class std::future<int>;
|
||||
template class std::future<int&>;
|
||||
template class std::future<void>;
|
||||
template class std::future<ClassType>;
|
||||
template class std::future<ClassType&>;
|
||||
|
|
|
@ -25,9 +25,8 @@
|
|||
#include <testsuite_tr1.h>
|
||||
|
||||
using namespace __gnu_test;
|
||||
using std::packaged_task;
|
||||
template class packaged_task<int()>;
|
||||
template class packaged_task<int&()>;
|
||||
template class packaged_task<void()>;
|
||||
template class packaged_task<ClassType(int)>;
|
||||
template class packaged_task<AbstractClass&(int)>;
|
||||
template class std::packaged_task<int()>;
|
||||
template class std::packaged_task<int&()>;
|
||||
template class std::packaged_task<void()>;
|
||||
template class std::packaged_task<ClassType(int)>;
|
||||
template class std::packaged_task<AbstractClass&(int)>;
|
||||
|
|
|
@ -25,9 +25,8 @@
|
|||
#include <testsuite_tr1.h>
|
||||
|
||||
using namespace __gnu_test;
|
||||
using std::promise;
|
||||
template class promise<int>;
|
||||
template class promise<int&>;
|
||||
template class promise<void>;
|
||||
template class promise<ClassType>;
|
||||
template class promise<ClassType&>;
|
||||
template class std::promise<int>;
|
||||
template class std::promise<int&>;
|
||||
template class std::promise<void>;
|
||||
template class std::promise<ClassType>;
|
||||
template class std::promise<ClassType&>;
|
||||
|
|
|
@ -25,9 +25,8 @@
|
|||
#include <testsuite_tr1.h>
|
||||
|
||||
using namespace __gnu_test;
|
||||
using std::shared_future;
|
||||
template class shared_future<int>;
|
||||
template class shared_future<int&>;
|
||||
template class shared_future<void>;
|
||||
template class shared_future<ClassType>;
|
||||
template class shared_future<ClassType&>;
|
||||
template class std::shared_future<int>;
|
||||
template class std::shared_future<int&>;
|
||||
template class std::shared_future<void>;
|
||||
template class std::shared_future<ClassType>;
|
||||
template class std::shared_future<ClassType&>;
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
#include <ext/numeric_traits.h>
|
||||
|
||||
using __gnu_cxx::__numeric_traits;
|
||||
template struct __numeric_traits<short>;
|
||||
template struct __numeric_traits<unsigned short>;
|
||||
template struct __numeric_traits<double>;
|
||||
template struct __gnu_cxx::__numeric_traits<short>;
|
||||
template struct __gnu_cxx::__numeric_traits<unsigned short>;
|
||||
template struct __gnu_cxx::__numeric_traits<double>;
|
||||
|
|
|
@ -23,8 +23,7 @@
|
|||
// { dg-do compile }
|
||||
|
||||
using namespace __gnu_test;
|
||||
using std::tr1::enable_shared_from_this;
|
||||
template class enable_shared_from_this<int>;
|
||||
template class enable_shared_from_this<void>;
|
||||
template class enable_shared_from_this<ClassType>;
|
||||
template class enable_shared_from_this<IncompleteClass>;
|
||||
template class std::tr1::enable_shared_from_this<int>;
|
||||
template class std::tr1::enable_shared_from_this<void>;
|
||||
template class std::tr1::enable_shared_from_this<ClassType>;
|
||||
template class std::tr1::enable_shared_from_this<IncompleteClass>;
|
||||
|
|
|
@ -23,8 +23,7 @@
|
|||
// { dg-do compile }
|
||||
|
||||
using namespace __gnu_test;
|
||||
using std::tr1::shared_ptr;
|
||||
template class shared_ptr<int>;
|
||||
template class shared_ptr<void>;
|
||||
template class shared_ptr<ClassType>;
|
||||
template class shared_ptr<IncompleteClass>;
|
||||
template class std::tr1::shared_ptr<int>;
|
||||
template class std::tr1::shared_ptr<void>;
|
||||
template class std::tr1::shared_ptr<ClassType>;
|
||||
template class std::tr1::shared_ptr<IncompleteClass>;
|
||||
|
|
|
@ -26,8 +26,7 @@
|
|||
// library this checks the templates can be instantiated for non-default
|
||||
// lock policy, for a single-threaded lib this is redundant but harmless.
|
||||
using namespace __gnu_test;
|
||||
using std::tr1::__shared_ptr;
|
||||
using std::tr1::_S_single;
|
||||
template class __shared_ptr<int, _S_single>;
|
||||
template class __shared_ptr<ClassType, _S_single>;
|
||||
template class __shared_ptr<IncompleteClass, _S_single>;
|
||||
template class std::tr1::__shared_ptr<int, _S_single>;
|
||||
template class std::tr1::__shared_ptr<ClassType, _S_single>;
|
||||
template class std::tr1::__shared_ptr<IncompleteClass, _S_single>;
|
||||
|
|
|
@ -23,8 +23,7 @@
|
|||
// { dg-do compile }
|
||||
|
||||
using namespace __gnu_test;
|
||||
using std::tr1::weak_ptr;
|
||||
template class weak_ptr<int>;
|
||||
template class weak_ptr<void>;
|
||||
template class weak_ptr<ClassType>;
|
||||
template class weak_ptr<IncompleteClass>;
|
||||
template class std::tr1::weak_ptr<int>;
|
||||
template class std::tr1::weak_ptr<void>;
|
||||
template class std::tr1::weak_ptr<ClassType>;
|
||||
template class std::tr1::weak_ptr<IncompleteClass>;
|
||||
|
|
|
@ -26,9 +26,8 @@
|
|||
// library this checks the templates can be instantiated for non-default
|
||||
// lock policy, for a single-threaded lib this is redundant but harmless.
|
||||
using namespace __gnu_test;
|
||||
using std::tr1::__weak_ptr;
|
||||
using std::tr1::_S_single;
|
||||
template class __weak_ptr<int, _S_single>;
|
||||
template class __weak_ptr<void, _S_single>;
|
||||
template class __weak_ptr<ClassType, _S_single>;
|
||||
template class __weak_ptr<IncompleteClass, _S_single>;
|
||||
template class std::tr1::__weak_ptr<int, _S_single>;
|
||||
template class std::tr1::__weak_ptr<void, _S_single>;
|
||||
template class std::tr1::__weak_ptr<ClassType, _S_single>;
|
||||
template class std::tr1::__weak_ptr<IncompleteClass, _S_single>;
|
||||
|
|
|
@ -24,27 +24,25 @@
|
|||
#include <string>
|
||||
#include <tr1/functional>
|
||||
|
||||
using namespace std::tr1;
|
||||
|
||||
// Verify that we can instantiate hash for every required type.
|
||||
template class hash<bool>;
|
||||
template class hash<char>;
|
||||
template class hash<signed char>;
|
||||
template class hash<unsigned char>;
|
||||
template class hash<short>;
|
||||
template class hash<int>;
|
||||
template class hash<long>;
|
||||
template class hash<unsigned short>;
|
||||
template class hash<unsigned int>;
|
||||
template class hash<unsigned long>;
|
||||
template class hash<float>;
|
||||
template class hash<double>;
|
||||
template class hash<long double>;
|
||||
template class hash<void*>;
|
||||
template class hash<std::string>;
|
||||
template class std::tr1::hash<bool>;
|
||||
template class std::tr1::hash<char>;
|
||||
template class std::tr1::hash<signed char>;
|
||||
template class std::tr1::hash<unsigned char>;
|
||||
template class std::tr1::hash<short>;
|
||||
template class std::tr1::hash<int>;
|
||||
template class std::tr1::hash<long>;
|
||||
template class std::tr1::hash<unsigned short>;
|
||||
template class std::tr1::hash<unsigned int>;
|
||||
template class std::tr1::hash<unsigned long>;
|
||||
template class std::tr1::hash<float>;
|
||||
template class std::tr1::hash<double>;
|
||||
template class std::tr1::hash<long double>;
|
||||
template class std::tr1::hash<void*>;
|
||||
template class std::tr1::hash<std::string>;
|
||||
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
template class hash<wchar_t>;
|
||||
template class hash<std::wstring>;
|
||||
template class std::tr1::hash<wchar_t>;
|
||||
template class std::tr1::hash<std::wstring>;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -30,13 +30,13 @@ using std::allocator;
|
|||
using std::pair;
|
||||
using std::equal_to;
|
||||
|
||||
template class unordered_map<string, float>;
|
||||
template class unordered_map<string, int,
|
||||
template class std::tr1::unordered_map<string, float>;
|
||||
template class std::tr1::unordered_map<string, int,
|
||||
hash<string>, equal_to<string>,
|
||||
allocator<pair<const string, int> > >;
|
||||
template class unordered_map<string, float,
|
||||
template class std::tr1::unordered_map<string, float,
|
||||
hash<string>, equal_to<string>,
|
||||
allocator<char> >;
|
||||
template class __unordered_map<string, int,
|
||||
template class std::tr1::__unordered_map<string, int,
|
||||
hash<string>, equal_to<string>,
|
||||
allocator<pair<const string, int> >, true>;
|
||||
|
|
|
@ -30,13 +30,13 @@ using std::equal_to;
|
|||
using std::allocator;
|
||||
using std::pair;
|
||||
|
||||
template class unordered_multimap<string, float>;
|
||||
template class unordered_multimap<string, int,
|
||||
template class std::tr1::unordered_multimap<string, float>;
|
||||
template class std::tr1::unordered_multimap<string, int,
|
||||
hash<string>, equal_to<string>,
|
||||
allocator<pair<const string, int> > >;
|
||||
template class unordered_multimap<string, float,
|
||||
template class std::tr1::unordered_multimap<string, float,
|
||||
hash<string>, equal_to<string>,
|
||||
allocator<char> >;
|
||||
template class __unordered_multimap<string, int,
|
||||
template class std::tr1::__unordered_multimap<string, int,
|
||||
hash<string>, equal_to<string>,
|
||||
allocator<pair<const string, int> >, true>;
|
||||
|
|
|
@ -27,10 +27,10 @@ using namespace std::tr1;
|
|||
using std::equal_to;
|
||||
using std::allocator;
|
||||
|
||||
template class unordered_multiset<int>;
|
||||
template class unordered_multiset<float, hash<float>, equal_to<float>,
|
||||
template class std::tr1::unordered_multiset<int>;
|
||||
template class std::tr1::unordered_multiset<float, hash<float>, equal_to<float>,
|
||||
allocator<float> >;
|
||||
template class unordered_multiset<int, hash<int>, equal_to<int>,
|
||||
template class std::tr1::unordered_multiset<int, hash<int>, equal_to<int>,
|
||||
allocator<char> >;
|
||||
template class __unordered_multiset<float, hash<float>, equal_to<float>,
|
||||
template class std::tr1::__unordered_multiset<float, hash<float>, equal_to<float>,
|
||||
allocator<float>, true>;
|
||||
|
|
|
@ -27,10 +27,10 @@ using namespace std::tr1;
|
|||
using std::equal_to;
|
||||
using std::allocator;
|
||||
|
||||
template class unordered_set<int>;
|
||||
template class unordered_set<float, hash<float>, equal_to<float>,
|
||||
allocator<float> >;
|
||||
template class unordered_set<int, hash<int>, equal_to<int>,
|
||||
allocator<char> >;
|
||||
template class __unordered_set<float, hash<float>, equal_to<float>,
|
||||
allocator<float>, true>;
|
||||
template class std::tr1::unordered_set<int>;
|
||||
template class std::tr1::unordered_set<float, hash<float>, equal_to<float>,
|
||||
allocator<float> >;
|
||||
template class std::tr1::unordered_set<int, hash<int>, equal_to<int>,
|
||||
allocator<char> >;
|
||||
template class std::tr1::__unordered_set<float, hash<float>, equal_to<float>,
|
||||
allocator<float>, true>;
|
||||
|
|
Loading…
Add table
Reference in a new issue