参考模板c++
refering to Templates c++
考虑模板Class
我们什么时候必须显式引用模板,以及编译器什么时候 "understands that we meant it"
考虑到以下情况:
1) 函数 return 价值和争论
2) 函数内的变量声明
3) 命名空间 SomeClass<T>::
与 SomeClass::
有什么规定吗?我看到有时使用的是:
SomeClass
有时:SomeClass<T>
我没听懂规则
Class 模板参数可能 仅 在 class 的实现中被省略,其中它们隐式地将适当的模板说明符添加到 class 并且在引用非依赖基 class 时(如 "does not reuse any template arguments" 中的非依赖)。例如:
template<typename T, typename U>
class C { /* here C is the same as C<T, U> */ };
template<typename T>
class C<void, T> { /* here C is the same as C<void, T> */ };
template<>
class C<void, void> { /* here C is the same as C<void, void> */ };
template<typename> struct Base { };
struct DerivedA : Base<void>
{ /* here Base is the same as Base<void> */ };
template<typename T>
struct DerivedB : Base<T>
{ /* here Base is invalid, since Base<T> depends on a template argument */ };
函数模板可以省略它们的模板参数,如果它们可以从它们的参数中推导出来的话:
template<typename T>
void f(T f);
f(3); // equivalent to f<int>(3) if no other overload exists
此外,还有默认模板参数,这导致 something really funky:
template<typename T = void>
class D
{
// Here D is D<T>, but D<> is D<void> instead!
};
标准描述了[temp.local]中的所有场景:
Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injected-class-name can be used as
a template-name or a type-name. When it is used with a
template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the
elaborated-type-specifier of a friend class template declaration, it refers to the class template itself. Otherwise, it is equivalent to
the template-name followed by the template-parameters of the class
template enclosed in <>
.
Within the scope of a class template specialization or partial specialization, when the injected-class-name is used as a type-name,
it is equivalent to the template-name followed by the
template-arguments of the classtemplate specialization or partial
specialization enclosed in <>
.
[ Example:
template<template<class> class T> class A { };
template<class T> class Y;
template<> class Y<int> {
Y* p; // meaning Y<int>
Y<char>* q; // meaning Y<char>
A<Y>* a; // meaning A<::Y>
class B {
template<class> friend class Y; // meaning ::Y
};
};
—end example ]
这仅在 class 模板内部有效(即注入-class-名称的范围),并且仅当从相应范围访问该名称时才有效:
When the normal name of the template (i.e., the name from the
enclosing scope, not the injected-class-name) is used, it always
refers to the class template itself and not a specialization of the
template. [ Example:
template<class T> class X {
X* p; // meaning X<T>
X<T>* p2;
X<int>* p3;
::X* p4; // error: missing template argument list
// ::X does not refer to the injected-class-name
};
—end example ]
对于基 classes,基不相关:
A lookup that finds an injected-class-name (10.2) can result in an
ambiguity in certain cases (for example, if it is found in more than
one base class). If all of the injected-class-names that are found
refer to specializations of the same class template, and if the name
is used as a template-name, the reference refers to the class
template itself and not a specialization thereof, and is not
ambiguous. [ Example:
template <class T> struct Base { };
template <class T> struct Derived: Base<int>, Base<char> {
typename Derived::Base b; // error: ambiguous
typename Derived::Base<double> d; // OK
};
—end example ]
我们可以稍微修改示例以显示有效内容:
template <class T> struct Base { };
template <class T> struct Derived: Base<char> {
typename Derived::Base b; // Ok: b refers to Base<char>
};
考虑模板Class 我们什么时候必须显式引用模板,以及编译器什么时候 "understands that we meant it"
考虑到以下情况:
1) 函数 return 价值和争论
2) 函数内的变量声明
3) 命名空间 SomeClass<T>::
与 SomeClass::
有什么规定吗?我看到有时使用的是:
SomeClass
有时:SomeClass<T>
我没听懂规则
Class 模板参数可能 仅 在 class 的实现中被省略,其中它们隐式地将适当的模板说明符添加到 class 并且在引用非依赖基 class 时(如 "does not reuse any template arguments" 中的非依赖)。例如:
template<typename T, typename U>
class C { /* here C is the same as C<T, U> */ };
template<typename T>
class C<void, T> { /* here C is the same as C<void, T> */ };
template<>
class C<void, void> { /* here C is the same as C<void, void> */ };
template<typename> struct Base { };
struct DerivedA : Base<void>
{ /* here Base is the same as Base<void> */ };
template<typename T>
struct DerivedB : Base<T>
{ /* here Base is invalid, since Base<T> depends on a template argument */ };
函数模板可以省略它们的模板参数,如果它们可以从它们的参数中推导出来的话:
template<typename T>
void f(T f);
f(3); // equivalent to f<int>(3) if no other overload exists
此外,还有默认模板参数,这导致 something really funky:
template<typename T = void>
class D
{
// Here D is D<T>, but D<> is D<void> instead!
};
标准描述了[temp.local]中的所有场景:
Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injected-class-name can be used as a template-name or a type-name. When it is used with a template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-type-specifier of a friend class template declaration, it refers to the class template itself. Otherwise, it is equivalent to the template-name followed by the template-parameters of the class template enclosed in
<>
.Within the scope of a class template specialization or partial specialization, when the injected-class-name is used as a type-name, it is equivalent to the template-name followed by the template-arguments of the classtemplate specialization or partial specialization enclosed in
<>
.[ Example:
template<template<class> class T> class A { }; template<class T> class Y; template<> class Y<int> { Y* p; // meaning Y<int> Y<char>* q; // meaning Y<char> A<Y>* a; // meaning A<::Y> class B { template<class> friend class Y; // meaning ::Y }; };
—end example ]
这仅在 class 模板内部有效(即注入-class-名称的范围),并且仅当从相应范围访问该名称时才有效:
When the normal name of the template (i.e., the name from the enclosing scope, not the injected-class-name) is used, it always refers to the class template itself and not a specialization of the template. [ Example:
template<class T> class X { X* p; // meaning X<T> X<T>* p2; X<int>* p3; ::X* p4; // error: missing template argument list // ::X does not refer to the injected-class-name };
—end example ]
对于基 classes,基不相关:
A lookup that finds an injected-class-name (10.2) can result in an ambiguity in certain cases (for example, if it is found in more than one base class). If all of the injected-class-names that are found refer to specializations of the same class template, and if the name is used as a template-name, the reference refers to the class template itself and not a specialization thereof, and is not ambiguous. [ Example:
template <class T> struct Base { }; template <class T> struct Derived: Base<int>, Base<char> { typename Derived::Base b; // error: ambiguous typename Derived::Base<double> d; // OK };
—end example ]
我们可以稍微修改示例以显示有效内容:
template <class T> struct Base { };
template <class T> struct Derived: Base<char> {
typename Derived::Base b; // Ok: b refers to Base<char>
};